力扣27 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2,
并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5,
并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
改变元素的相对位置
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i = 0, j = nums.size() - 1, xj = 0;
while (i <= j) {
if (nums[i] == val) {
//xj++;
nums[i] = nums[j];
//j -= xj; // xj是数组末尾移到最前面减少的元素
j--;
}
else if (nums[i] != val) {
i++;
}
}
return ++j;
}
};
不改变相对位置的话
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
实现思路:定义两个int值作为“指针”指向原数组开头,以fast快指针为基准开始遍历nums数组,用slow指针记录新数组(保留值构成的数组),即索引保留值
slow如何实现记录新数组——索引保留值 当fast快指针遍历数组,索引值!=val值,即保留值时,slow++(新数组长度+1); 当fast快指针遍历数组,索引值==val值,即删除值时,slow不变(新数组长度不变);
fast快指针:寻找新数组里所需要的元素; 遍历原数组,得到索引值; slow慢指针:需要更新的位置; 根据索引值是否val值,删除值/保留值 当fast快指针遍历数组结束,得到的slow值即新数组长度
快慢指针法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++; //发现快指针指向保留值,slowIndex可+1
// nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
力扣977 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入: nums = [-4,-1,0,3,10]
输出: [0,1,9,16,100]
解释: 平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入: nums = [-7,-3,2,3,11]
输出: [4,9,9,49,121]
暴力
class Solution {
public:
void quickSort(vector<int>& q, int l, int r) {
if (l >= r) return;
int x = q[l], i = l - 1, j = r + 1;
while (i < j) {
do i++; while (q[i] < x);
do j--; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quickSort(q, l, j);
quickSort(q, j + 1, r);
}
vector<int> sortedSquares(vector<int>& nums) {
for (int i = 0; i < nums.size(); i++){
nums[i] *=nums[i];
}
quickSort(nums, 0, nums.size() - 1);
// sort(nums.begin(), nums.end()); // sort快速排序 shit 可以直接这样
return nums;
}
};
方法2 双指针法 前后指针
数组其实是有序的, 只不过负数平方之后可能成为最大数了。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
此时可以考虑双指针法了,i指向起始位置,j指向终止位置。
定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。
如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。
如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i]; 。
// 双指针法 前后指针
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int i = 0, j = nums.size() - 1, x = j;
vector<int> q(nums.size());
while (i != j) {
if (nums[i]*nums[i] > nums[j]*nums[j]) {
q[x--] = nums[i]*nums[i];
i++;
} else {
q[x--] = nums[j]*nums[j];
j--;
}
}
q[x] = nums[j]*nums[j];
return q;
}
};