数组
3. 移除元素
思路:
首尾同时进行的双指针,将等于 val 的位置和从后往前数第一个不等于 val 的值交换位置。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int nums_size = nums.size();
if (nums_size == 0) return 0;
int left = 0, right = nums_size - 1;
while (left < right) {
if (nums[left] == val && nums[right] != val) {
swap(nums[left++], nums[right--]);
} else if (nums[left] == val && nums[right] == val) {
while (left < right && nums[right] == val) right--;
if (left < right) swap(nums[left++], nums[right--]);
} else {
left++;
}
}
return nums[left] == val ? left : left + 1;
}
};
思路2:
还是卡哥的快慢指针好理解一点:
快指针遍历找到不等于 val 的值放到 slowIndex 的位置,slowIndex 向后移动一位。最后数组的有效长度,即为 slowIndex 位置之前的所有值。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int nums_size = nums.size();
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums_size; fastIndex++) {
if (nums[fastIndex] != val) nums[slowIndex++] = nums[fastIndex];
}
return slowIndex;
}
};
4. 有序数组的平方
思路:
两个指针 left 和 right 分别放在数组的首尾,选择绝对值大的放到结果数组的尾部,该指针向中间移动一次。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int nums_size = nums.size();
vector<int> result(nums_size, 0);
int left = 0, right = nums_size - 1;
int cnt = nums_size - 1;
while (left <= right) {
result[cnt--] = abs(nums[left]) > abs(nums[right]) ? pow(nums[left++], 2) : pow(nums[right--], 2);
}
return result;
}
};
5. 长度最小的子数组
思路:
滑动窗口,右边扩张,左边收缩,一边收缩一边更新答案。
注意题干说的是 大于等于 我按等于写了半天,样例出错了还纳闷了半天。。。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int nums_size = nums.size();
int ans = 100000 + 5;
long long sum = 0;
int slowIndex = 0, fastIndex = 0;
for (fastIndex = 0; fastIndex < nums_size; fastIndex++) {
sum += nums[fastIndex];
while (sum >= target) {
ans = min(ans, fastIndex - slowIndex + 1);
sum -= nums[slowIndex++];
}
}
return ans == 100005 ? 0 : ans;
}
};