代码随想录打卡第二天 | leetcode-977&209&59

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++;
      }

59-螺旋矩阵 II(白天补充)

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铁中棠ang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值