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

 977.有序数组的平方 

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

文章讲解:代码随想录

视频讲解: 双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

 第一种解法:暴力

  • 直接遍历整个数组,对每个数平方,然后调用库函数,sort(nums.begin(),nums.end())进行快速排序

代码实现

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        for (int i = 0; i < nums.size(); i++)
        {
            nums[i] *= nums[i];
        }
        sort(nums.begin(), nums.end());
        return nums;
    }
};

第二种解法:双指针法

自己思考

和第27题移除元素一样,很自然的想到了快慢指针,一个指针寻找新数组中所需要的元素,一个指针用来更新数组。每一个数的平方跟下一个数的平方进行比较交换位置。我没有想到这是一个有序的数组,且数组平方最大的元素一定是在两边。和移除元素不一样的是,双指针并不是从左到右的一个移动方式,而是向中间合拢的一个过程。

解题思路

  1. 思考双指针的走向,是向中间合拢的过程
  2. 首先要创建一个新数组vector<int> result(nums.size(),0),一个指针指向数组中的元素,因为要求非递减顺序排列,即递增的顺序,最大的数在最右边,两边的元素平方是最大的数,指针由外向内合拢的过程是为了找到最大的数,所以我们按最大的下标到最小的下标依次放入元素。
  3. 对头部指针指向的元素的平方和尾部指针指向元素的平方进行比较(这里的指针其实是数组的下标),谁大谁就先放入数组中,依次移动,直到两个指针相等,将最后一个元素放入新数组。
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> result(nums.size(),0);
        int k = nums.size() - 1;
        for (int head = 0,tail = nums.size() - 1; head <= tail; )
        {
            if (nums[head] * nums[head]> nums[tail] * nums[tail])
            {
                result[k--] = nums[head] * nums[head];
                head++;
            }
            else 
            {
               result[k--] = nums[tail] * nums[tail]; 
               tail--;
            }

        }
        return result;
    }
};

遇到的问题

  • vector初始化需要指明
  • 除了定义一个头指针和一个尾指针,对新创建的数组也要定义一个指针,指向该数组下标最大的位置,不能用尾指针代替,因为两个的变化时刻不同。
  • 在写一个数的平方时,写成了(nums[head])^2,C++中没有平方运算符,只能用幂函数和乘积的方法代替。

209.长度最小的子数组

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

文章讲解:代码随想录

视频讲解:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili

解题思路 

  1. j指向终止位置,i为初始位置,subLength为滑动窗口的长度。
  2. ​使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件。
  3. 更新sumi值。
  4. INT32_MAX 是指 int 可以去的最大数,如果最后的结果还是这个就说明没有匹配的,就返回 0,有匹配的就返回 result

代码实现

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

    }
};

出现的问题

  • 一开始不懂INT32_MAX是什么,为什么要写return result == INT32_MAX ? 0 : result;
  • sum要减去i起始位置的数,窗口是向右移动的,写成了sum -= nums[j]

59.螺旋矩阵II

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

文章讲解:代码随想录

视频讲解:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili

解题思路

  1. 首先要有循环不变量的思想,遍历每条边都采用相同的方式且每条边遍历的元素个数都相等。
  2. 知道二维数组i为行,j为列,定义ystartxstart分别表示列和行的起始位置,用offset来控制终止位置。
  3. 如果n为奇数,需要在最后为中间的数赋值。

代码实现 

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
      vector<vector<int>> num(n, vector<int>(n, 0));
      int startx = 0,starty = 0;
      int offset = 1;
      int count = 1;
      int i,j;
      int loop = n / 2;
      while (loop--)
      {
        i = startx;
        j = starty;
        for (j = starty; j < n - offset; j++)
          num[startx][j] = count++;
        for (i = startx; i < n - offset; i++)
          num[i][j] = count++;
        for (; j > starty; j--)
          num[i][j] = count++;
        for (; i > startx; i--)
          num[i][j] = count++;
        startx++;
        starty++;
        offset++;
      }
      if (n % 2)
        num[n/2][n/2] = count;
      return num;
    }
};

出现的问题

  • while循环知道要执行n/2次,但将条件这个条件写成了while(n/2)n/2一直为真,所以该循环会永远执行下去。
  • 忘记每循环一周需要改变startxstartyoffset

总结

加上写博客,非常痛苦的四个小时,数组专题终于结束了,一直在安慰自己,第一遍需要看讲解思路是正常的,多刷几遍会越来越好,emmmm。。。坚持啊,每弄懂一道题还挺有成就感!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值