代码随想录 day 2

第一章 数组part02

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

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

59.螺旋矩阵II

题目建议: 本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义,在这里又用上了。
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/

**总结 **

题目建议:希望大家 也做一个自己 对数组专题的总结
文章链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E6%80%BB%E7%BB%93%E7%AF%87.html

977.有序数组的平方

题目链接

https://leetcode.cn/problems/squares-of-a-sorted-array/

解题思路

首先这题要根据题的说明,是一个非递减数组,负数平方是正有可能超过正数的平方,那么在这个数组最大最小值一定出现在头部或尾部 ,在这个数组的任意一个子数组都是如此。 头尾双指针解决。
这题只能以空间换时间,不断缩数组,取头尾的最大值赋值给新数组的 尾部->0的位置。
总结踩坑:刚开始一直想在本数组操作,想空间复杂度O(1),那么一定会破环这个非递减数组的特性,导致无法解出本题。 所以这里不要破坏原数组,要把结果收集到新数组上。

code

public int[] sortedSquares(int[] nums) {
        //因为是有序数组,这个想到平方后的最大数一定在俩边
        //每次把最大的选出来,左指针+1 或 右指针-1
        //要定义个新的result数组存储结果集
        int left=0;
        int right=nums.length-1;
        int[] result=new int[nums.length];
        int index=nums.length-1;
        while(left<=right){
            if(Math.abs(nums[left])>Math.abs(nums[right])){
                result[index--]=nums[left]*nums[left];
                left++;
            }else{
                result[index--]=nums[right] * nums[right];
                right--;
            }
        }
        return result;
    }

209.长度最小的子数组

题目链接

https://leetcode.cn/problems/minimum-size-subarray-sum/

解题思路

O(n) 复杂度 一个for循环解决问题,题目说最小子数组,可以联想到滑动窗口问题
1.找到满足的窗口,继续找下一个窗口,看那个窗口最满足题目要求
2.循环的索引需要考虑,这个索引是窗口的起始位置还是终止位置呢?
假设起始位置,开始从头遍历,找到了一个符合的窗口,此时索引来到这个符合窗口的终止位置,索引循环的索引一定是窗口的终止位置。
3.确定了窗口的终止位置,那么要考虑窗口的起始位置,初始的窗口起始位置一定是0,此时找到了一个符合的窗口,那么就要开始找下一个窗口,这时窗口的起始位置就要变动了,窗口向前移动,直到遇到某个窗口不符合结果,那么窗口的终止位置就要开始变动了直到在遇到符合的窗口,周而复始直到循环结束。
4.时间复杂度分析
终止窗口扫描每一个元素O(n) 起始窗口扫描每一个元素O(n) , O(2n) 所以时间复杂度是O(n)

code

public int minSubArrayLen(int target,int[] nums){
        if(nums==null || nums.length==0){
            return 0;
        }
        //收集结果,如果值没有变化返回0即没有收集到结果
        int length=Integer.MAX_VALUE;
        //窗口起始位置
        int left=0;
        //这个窗口的值
        int sum=0;
        for(int right=0;right<nums.length;right++){
            //窗口变化记录sum
            sum+=nums[right];
            //找到符合的右窗口位置
            while(sum>=target){
                //收集右窗口第一次满足的结果
                length=Math.min(length,right-left+1);
                //窗口左边开始变化,直到遇到不满足的左窗口
                sum-=nums[left];
                left++;
            }
            
        }
        return length==Integer.MAX_VALUE?0:length;
    }

总结:所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果,
** 考虑好循环的索引是窗口的终止位置,然后在控制窗口的起始位置是解题的关键**

59.螺旋矩阵II

题目链接

https://leetcode.cn/problems/spiral-matrix-ii/

解题思路

控制好边界,维持左闭右开,每条边处理相同数量的空格,不要越界,这样才好写代码不容易乱
考虑遍历几次,奇数少循环一圈,矩阵中间的位置要单独处理
写的时候代入例子自然就通过了。

code

//保持边界条件左闭右开 循环不变量
    public int[][] generateMatrix(int n) {
         //定义二维数组收集结果
        int[][] res=new int[n][n];
        //定义数组的起始位置
        int x=0,y=0;
        //定义循环几圈,n为奇数 必定少循环一圈,矩阵中间的位置要单独处理
        int loop=n/2;
        int count = 1; // 用来给矩阵赋值 他控制1-n*n的数赋值给二维数组
        int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
        int i,j;
        while (loop-->0){
            i=x;
            j=y;
            //第一条边 保持左闭右开 i=0 j=0
            for (;j<n-offset;j++){
                res[i][j]=count++;
            }
            //第二条边  i=0 j=2
            for(;i<n-offset;i++){
                res[i][j]=count++;
            }
            //第三条边  i=2,j=2
            for(;j>=offset;j--){
                res[i][j]=count++;
            }
            //第4条边 i=2 j=0;
            for(;i>=offset;i--){
                res[i][j]=count++;
            }
            //第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
            x++;
            y++;
            // offset 控制每一圈里每一条边遍历的长度
            offset++;
        }
        if(n%2==1){
            int mid=n/2;
            res[mid][mid]=count;
        }
        return res;

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值