代码随想录算法训练营第二天 | Leetcode 977 有序数组的平方 Leetcode 209 长度最小的子数组 Leetcode 59 螺旋矩阵Ⅱ

前言

今天的题目主要涉及到双指针,理解双指针的目的之后就不难,螺旋矩阵在大二考试时写过但没写出来,这次有了更好的理解。

Leetcode 977 有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/description/

代码随想录题解:代码随想录 (programmercarl.com)

思路:这个题的数组为有序数组且有负数,那么平方之后的最大值肯定在数组的两端,然后大小依次向中间递减。题目要求我们按递增顺序排列平方结果,那么我们结果数组就从尾部开始存即可。双指针在题目中起到的作用主要是遍历寻找当前数组最大值。

代码:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
    vector<int> result(nums.size(),0);
    int k=nums.size()-1;
    for(int i=0,j=nums.size()-1;i<=j;)
    {
        if(nums[i]*nums[i]>nums[j]*nums[j])
        {
            result[k]=nums[i]*nums[i];
            k--;
            i++;
        }
        else
        {
            result[k]=nums[j]*nums[j];
            k--;
            j--;
        }
       
    }
    return result;
    }
};

Leetcode 209 长度最小的子数组

思路:滑动窗口,用双指针模拟窗口滑动,一个左边界,一个右边界。先让右边界变大,如果发现和超过target,证明此时这个窗口里的子数组满足题意,先记录长度,然后缩小左边界并记录长度直到和小于target,此时应该增大有边界,最终结束条件为右边界抵达数组尾部。

代码:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
     int i=0;
     int j=0;
     int result=INT32_MAX;
     int sum=0;
     int len=0;
    for(j=0;j<nums.size();j++)
    {
        sum+=nums[j];
        while(sum>=target)
        {
            len=j-i+1;
            if(result>=len)
            {
             result=len;
            }
            else
            {
             result=result;
            }
            sum-=nums[i];
            i++;
        }
    }
    if (result==INT32_MAX)
    {
        return 0;
    }
    return result;
    }
};

Leetcode 59 螺旋矩阵Ⅱ

思路:拿n=3举例,想清楚四个角什么时候填值,最好的想法是每个角就留给每次循环的第一个,即左上给第一次,遍历到右上不赋值右上,右上交给第二次,遍历到右下不赋值右下,右下交给第三次以此类推。还需要注意转几圈,这个模拟一下即可。最后注意hang,lie,offset边界每次转完一圈要++以及n为奇数时最中心特殊赋值。

代码:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0));
        int hang=0;int lie=0;int i,j;int offset=1;int count=1;int loop=n/2;
        while(loop--)
        {
          for(j=lie;j<n-offset;j++) //注意结束条件
          {
            res[hang][j]=count;
            count++;
          }
          for(i=hang;i<n-offset;i++) //注意结束条件
          {
            res[i][j]=count;
            count++;
          }
          for(;j>lie;j--) //注意结束条件
          {
            res[i][j]=count;
            count++;
          }
          for(;i>hang;i--) //注意结束条件
          {
            res[i][j]=count;
            count++;
          }
          hang++;  //记得++
          lie++;
          offset++;
        }
        if(n%2==1)
        {
            res[n/2][n/2]=count;
        }
        return res;
    }
};

总结

我觉得算法既是一个理解的过程,也是一个记忆的过程,理解之后才能记得牢,记得牢证明已经理解,还是要多看多复盘。今天除此之外还学习了一点C++11的新特性,感觉对C++知识点的记忆体系还需要一段时间,时间还长继续加油。推荐一首最近很喜欢听的歌:种种可是(Anyway)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值