977-有序数组的平方
输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100]
暴力法
1、遍历计算平方;
2、排序;
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int i = 0; i < nums.size(); ++i){
nums[i] = nums[i] * nums[i];
}
sort(nums.begin(), nums.end());
return nums;
}
};
双指针
数组其实有序,只不过复数平方后为正,可能导致新数组和原来的顺序不一致;
那么新数组的最大值就在数组两端,不是左边就是右边,此时可考虑双指针;
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> ret(nums.size());
int left = 0;
int right = nums.size() - 1;
int idxVec = ret.size() - 1;
while(left <= right){
if(nums[left] * nums[left] < nums[right] * nums[right]){
ret.at(idxVec--) = nums[right] * nums[right];
right--;
}
else{
ret.at(idxVec--) = nums[left] * nums[left];
left++;
}
}
return ret;
}
};
209-长度最小的子数组
输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3]是该条件下的长度最小的子数组。
滑动窗口
1、使用左右指针分别标记子数组的起始和结束;
2、思考:什么时候移动左指针?什么时候移动右指针?
答:sum < target时:1、后移右指针!
sum = target时:1、后移左指针;2、sum -= nums[left] !3、后移右指针;
sum > target时:1、后移左指针;2、sum-=nums[left]!
注意: sum > target时,第一步不能后移右指针,因为有可能sum -= nums[left]之后就刚好sum == target了,如果第一步后移右指针,会导致sum > target,错过了一个sum==target的子数组;
举例:
输入:target = 5, nums = [1,3,2,2,4,3]
1、当left = 0, right = 2时, sum = 1 + 3 + 2 = 6 > 5
2、此时:left += 1, right = 2 sum = 3 + 2 == 5, 得到一个子数组{3,2};
如果再 left +=1时,right也后移一位为3->2, 则:sum = 3+2+2 > 5, 正好错过了{3,2}这个目标子数组;
3、这个逻辑该怎么实现呢?
sum = target和sum > target 的共同点:1、后移左指针;2、sum -= nums[left] !
所以:
while(sum >= target){ if(sum == target){ minLen = min(minLen, right - left + 1) //==时计算子数组长度 } sum -= nums[left++]; }
错误写法
以下错误代码说明(明天下班后补充,太晚了先睡觉)
举例:
//错误写法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left = 0, right = 0, minLen = INT_MAX;
int sum = 0;
while(right < nums.size()){
sum += nums[right++]; //right不是每次都需要++,此写法错误
if(sum == target){
minLen = min(minLen, right - left + 1);
sum -= nums[left++];
}
else if(sum < target){
}
else{//sum > target
sum -= nums[left++];
}
}
return minLen;
}
正确写法(还有用例不通过,后续研究研究)
target =11
[1,2,3,4,5]
预期结果:3,我怎么感觉这个预期有问题呢?? 哪个三位数子数组加起来==11。。
int minSubArrayLen(int target, vector<int>& nums) {
int left = 0, right = 0, minLen = INT_MAX;
int sum = 0;
while(right < nums.size()){
sum += nums[right];
while(sum >= target){
if(sum == target){
minLen = min(minLen, right - left + 1); //==时计算子数组长度
}
sum -= nums[left++];
}
right++;
}