mhkk的代码随想录算法训练营第二天

数组part2 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结

建议大家先独立做题,然后看视频讲解,然后看文章讲解,然后在重新做一遍题,把题目AC,最后整理成今日当天的博客

拓展题目可以先不做

详细布置

977.有序数组的平方

题目建议: 本题关键在于理解双指针思想

题目
文章

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

    }
};

209.长度最小的子数组

题目建议: 本题关键在于理解滑动窗口,这个滑动窗口看文字讲解 还挺难理解的,建议大家先看视频讲解。 拓展题目可以先不做。

题目
文章
视频

滑动窗口和普通暴力循环的区别: 暴力中的每组i,j都进行验证,除了满足超过target条件后的j会剪枝。而滑动窗口的过程是在继续,大于等于target时,计算是否为最优值,并去除最前面的值,使得再次不满足条件。

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX; // 最终的结果
        int sum = 0; // 子序列的数值之和
        int subLength = 0; // 子序列的长度
        //暴力解法
        for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
            sum = 0;
            for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
                sum += nums[j];
                if (sum >= s) { // 一旦发现子序列和超过了s,更新result
                    subLength = j - i + 1; // 取子序列的长度
                    result = result < subLength ? result : subLength;
                    break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
                }
            }
        }
        //滑动窗口法以j为终点
        for (int j = 0; j < nums.size(); j++) {
            sum += nums[j];
            // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
            while (sum >= s) {
                subLength = (j - i + 1); // 取子序列的长度
                result = result < subLength ? result : subLength;
                sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

59.螺旋矩阵II

题目建议: 本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义,在这里又用上了。

题目
文章
视频

该问题的核心是控制好开始和结束的地方,且每次转向后开始和结束有规律的变化,没有重复和遗漏
。使用二分法的循环不变量原则,左闭右开原则。
如果是奇数,最中间一个要特意写一下,因为右开会把他遗漏掉

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

总结

题目建议:希望大家 也做一个自己 对数组专题的总结

文章链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E6%80%BB%E7%BB%93%E7%AF%87.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值