代码随想录算法训练营day2

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

977.有序数组的平方题目链接leetcode 977 Squares of a Sorted Array

看到题目想考虑双指针,数组其实是有序的, 只不过负数平方之后可能成为最大数了。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int l = 0 , r = nums.length-1;      //起始位置指针和终止位置
        int[] res = new int[nums.length];   //保存答案
        int j = nums.length - 1;            //从终止位置保存
        while(l<=r){                        //利用二分
            if(nums[l]*nums[l]>nums[r]*nums[r]){    
                res[j--]=nums[l]*nums[l];    //对比两头的值,保存在res[j]
                l++;
            }else{
                res[j--]=nums[r]*nums[r];
                r--;
            }
        }
        return res;
    }
}

这道题不是快慢指针的形式,而是头尾指针向中间夹逼,

所以循环条件与之前不同。


209 长度最小数组 leetcode 209 Minimum Size Subarray Sum

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int start = 0,end = 0;                   //快慢指针
        int sum = 0,min=Integer.MAX_VALUE;       //设置一个最大值
        while(end < nums.length){                //遍历快指针
            sum +=nums[end++];                   //把每一个数组的值累加到sum
            while(sum>=target){                  //
                 min = Math.min(min,end - start);    //比较最大值和快指针和满指针位置差
                 sum -= nums[start];                 //再减去最前面的值
                 start++;                            //满指针移动
            }
        }
        return min == Integer.MAX_VALUE ? 0:min;     //比较
    }
}

滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果

实现滑窗功能需要想三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

题目中:

  • 窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
  • 窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
  • 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

其中为什么是while(sum >= target)因为容易存在target=101,nums=[1,1,1,1,100]的数组问题,

如果是if则无法解决此问题,所以用while

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

    59 螺旋矩阵II leetcode 59 Spiral Matrix II

  • class Solution {
        public int[][] generateMatrix(int n) {
            int l = 0 , r = n-1 , t = 0 , b = n -1; 
            int res[][] = new int[n][n];
            int sum = 1;                //设置开始值
            while(sum<=n*n){
                for( int i = l;i <= r;i++){//从左到右
                    res[t][i] = sum++;     //t是头层
                }
                t++;
                for(int i = t; i<=b;i++){//从上到下
                    res[i][r] = sum++;     //r是右层
                }
                r--;
                for(int i = r;i>=l;i--){//从右到左
                    res[b][i]= sum++;     //b是底层
                }
                b--;
                for(int i = b;i >= t; i--){//从下到上
                    res[i][l] = sum++;     //l是左层
                }
                l++;
            }
            return res;
        }
    }

    坚持循环不变量原则,每条边都坚持左闭右开,这样一圈下来才能按照统一规则画下来

     今天是三种题型

  • 1是双指针的夹逼

  • 2是滑动窗口

  • 3是模拟行为

 数组主要还是双指针算法,考虑边界问题还有条件的问题,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值