一:数组 day 2 977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II

977.有序数组的平方

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

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep 

    大型概括:双指针

    1.题目描述-->思路:

     给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

    2.输入 返回值:

        vector<int> sortedSquares(vector<int>& nums)

思路:

暴力解法01:各项先平方,再sort begin() end()

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
            int i = 0;
           for(i=0;i<nums.size();i++){        //写的while 忘记 i++了!
                nums[i] = nums[i]*nums[i];
            }
            sort(nums.begin(),nums.end());
            return nums;
    }
};

 双指针法02:step1:申请vector没有确定大小,超时了。

                        step2:双指针在首尾,收缩!!

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int>result(nums.size()); //申请vector大小 踩坑!
        int i = 0;
        int j = nums.size()-1;
        int k = j;
        while(i<=j){
            int x = nums[i];
            int y = nums[j];
            if(x<0&&-x>=y){      //慢指针动 当慢数值大的时候;
                result[k] = x*x;
                i++;
                k--;
                continue;
            }
            if(x<0&&-x<y||x>=0){          //快指针动,快的大
                result[k] = y*y;
                j--;
                k--;
                continue;
            }

        }
        return result;
    }
};

03:正版方法:逻辑判断的优化 

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int>result(nums.size()); //申请vector大小 踩坑!
        int i = 0;
        int j = nums.size()-1;
        int k = j;
    while(i<=j){
            int x = nums[i]*nums[i];
            int y = nums[j]*nums[j];
        if(x>y){
            result[k] = x;
            i++;
            k--;
        }
        else{result[k] = y;
             j--;k--;
        }
    }

     return result;
    }
};

    3.边界情况:(无)

    4.时间复杂度:O(n) O(n)

    5.进一步优化: 03 思路

209.长度最小的子数组

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

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE

    大型概括:双指针
    1.题目描述-->思路:


    2.输入 返回值:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int minLong = INT_MAX;
        int sum=0;//集合总和
        int i=0;
        for(int j=0;j<nums.size();j++){
                sum+=nums[j];
                while(sum>=target){         //一旦大于等于就开始  收缩窗口!
                    sum-=nums[i];
                    minLong=min(minLong,j-i+1);
                    i++;
                }            
        }
        return minLong==INT_MAX?0:minLong;

        } 
    };

59.螺旋矩阵II

题目

    大型概括:方法
           螺旋存储 123、、、n...n^2
    1.题目描述-->思路:

    2.输入 返回值:

  vector<vector<int>> generateMatrix(int n)

思路:step1:旋转后,每次留下最后一行

            step2:起始点偏移! 就是 starx++ stary++ !

             stpe3:注意offset 缩圈!

思路:
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
        int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
        int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
        int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
        int count = 1; // 用来给矩阵中每一个空格赋值
        int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
        int i,j;
        while (loop --) {
            i = startx;
            j = starty;

            // 下面开始的四个for就是模拟转了一圈
            // 模拟填充上行从左到右(左闭右开)
            for (j; j < n - offset; j++) {
                res[i][j] = count++;
            }
            // 模拟填充右列从上到下(左闭右开)
            for (i; i < n - offset; i++) {
                res[i][j] = count++;
            }
            // 模拟填充下行从右到左(左闭右开)
            for (; j > starty; j--) {
                res[i][j] = count++;
            }
            // 模拟填充左列从下到上(左闭右开)
            for (; i > startx; i--) {
                res[i][j] = count++;
            }

            // 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
            startx++;
            starty++;

            // offset 控制每一圈里每一条边遍历的长度
            offset += 1;
        }

        // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
        if (n % 2) {
            res[mid][mid] = count;
        }
        return res;
    }
};

    3.边界情况:左闭 右开

    4.时空复杂度:O(n^2) O(1)

    5.进一步优化:
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

计算机视觉入门

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

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

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

打赏作者

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

抵扣说明:

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

余额充值