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

LeetCode 977.有序数组的平方

题目链接:

LeetCode 977.有序数组的平方

看完题目后就想用两个for循环来做,但是这几天的刷题让我隐隐有一点新的想法,就是用左右两个指针来做。看了一眼代码随想录上的思路过后就直接跳过了暴力解法,转而用双指针法做。

文章链接:

代码随想录

由于这道题涉及到了平方,所以不难想到平方的最大值一定是在数组的两端。那么我们让两个指针分别指向数组两端。再定义一个尺寸和给出的数组一样大的数组,让另定义一个指针指向该数组的尾部,这道题就迎刃而解了。

代码如下:

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

可能得益于这几天的练习,已经可以较为轻松的解出这种难度的题目了。 

LeetCode 209. 长度最小的子序列

题目链接:

LeetCode 209. 长度最小的子序列

在代码随想录的文章中很形象的使用了滑动窗口这个词,不过这道题的本质还是使用快慢指针来做。

文章链接:

代码随想录

这道题用双指针法来做。其中,快指针(fast)用来把数组中的数收入num中,num就表示“窗口”内的子序列之和;慢指针(slow)用来将它指向的值剔除出“窗口”所包含的子序列。在代码随想录的文章中还有一张生动形象的图。那么用代码来实现该想法即为

代码如下

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

在纸上捋了一下思路之后再开始写代码发现思路会清晰很多,这个习惯也许可以保留。

LeetCode 59.螺旋矩阵II

题目链接:

LeetCode 59.螺旋矩阵II

这道题我想到了思路,但是在一些细节方面还是没有注意到,这个题不太涉及算法方面的知识,但是却有很多细节需要想清楚。

文章链接:

代码随想录

我想的思路是填入的时候把一行填入完了之后再进行下一行的填入,但是这样就会使代码更为复杂。正确的思路是填入到该行元素的个数减一的位置,至于该行的最后一个元素的填入就交给下一个for循环来做。还有就是和二分法一样的坚持一种区间的思想,因为这道题要注意的边界细节问题比较多,所以坚持一种思想才可以不让自己搞混。

代码如下:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> matrix(n, vector<int>(n, 0));
        int x = 0, y = 0, middle = n / 2, loop = n / 2, end = 1, num = 1, i, j;//x,y分别代表x轴,y轴的起始位置,middle代表二维数组最中间的位置,loop代表需要循环的次数,end用来控制每次遍历的长度,num用来赋值
        while (loop--) {
            i = x;
            j = y;
            for (j = y; j < n - end; j++) {//上面的一行从左到右填入
                matrix[x][j] = num++;
            }
            for (i = x; i < n - end; i++) {//右边的一行从上到下填入
                matrix[i][j] = num++;
            }
            for (; j > y; j--) {//下面的一行从右到左填入
                matrix[i][j] = num++;
            }
            for (; i > x; i--) {//左边的一行从下到上填入
                matrix[i][j] = num++;
            }
            x++; y++;//x,y表示了填入的起始位置,每次填入完成后都需要加一
            end += 1;
        }
        if (n % 2 != 0) {//如果n是奇数的话最中间的值就需要手动填入
            matrix[middle][middle] = n * n;
        }
        return matrix;//最后返回填入完成的二维数组
    }
};

从代码可以看出并不是太复杂,但是有很多元素的定义,需要同时兼顾几个元素的变化。这样的代码可以锻炼我们对于自己代码的掌控能力,以后有时间都可以拿出来重新做一做,多扣扣细节。

今日学习4小时收获

今天又一次加深了在数组方面的练习,可以看出数组其实不是想的那么简单,有一些算法还是需要我们熟练掌握的。今天收获了一道以后可以常常拿出来练手感的题,也就是螺旋矩阵这道题,还有就是巩固了昨天练习过的双指针法,能够更熟练的使用这种方法了。最后还是得多多重复,百炼成钢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值