【2】leetcode 977,209,59

文章详细解释了两种算法问题的解决方案:一是使用滑动窗口寻找非递减序列中满足条件的最小子数组,二是生成螺旋矩阵的算法,通过画圈的方式填充矩阵。文章探讨了这两个问题的思路和关键步骤,并提供了相应的代码实现。
摘要由CSDN通过智能技术生成

 977这道题思路清奇,最大的值一定在两边,所以用一个while循环向两边收拢。

但是有一点不太明白。题目说的是非递减序列,难道就是递增?不可以是【5,3,5】?

这个有空再研究。。

209也很有意思.滑动窗口,滑动窗口我们用一个s表示start,e表示end。

那么窗口就是   s和e之间的这一段,在滑动的时候,一会是e挪动,一会是s挪动,窗口长度不固定。

 为了求最小值,在for循环中,下标肯定是e

我现在举个例子:

  [2,3,1,2,4,3]  长度为7.

那么我们看输入,我们用一个s表示start,e表示end。

第一次。窗口为[2,2],和为2不大于7,说明以e结尾的没有大于7的,e挪s不挪。

第二次。窗口为[2,3],和为5不大于7,那么e继续挪,第三次就是[2,3,1]

到了第4次,[2,3,1,2]和为8说明这个时候说明区间里面的东西比7大了。我们先记下,此时长度为len = 4

 这个时候区间内以e=3结尾的会不会还有更小的?我们让s4往右边找找看。[3,1,2]此时小于7了

ok问题来了,这个时候我们肯定e是要右边挪了,那么s怎么处理?

s往左?那么下一次会变成下面的蓝色框的区间 ,可是有必要吗?蓝色框里面的红框之前不是已经算过了吗?

所以干嘛呢?s不动就好了,往右?那以当前s开头的子数组不找了是吧?

所以就是上面这个过程。s挪完e挪,大了就收s,小了就走e。

现在看代码:

class Solution {

    // 滑动窗口

    public int minSubArrayLen(int s, int[] nums) {

        int st = 0; //start,没办法上面输入是s不然我这个开始也叫s了。

        int sum = 0;

        int res = Integer.MAX_VALUE;

        for(int e=0;e<nums.length;e++){   //一个for循环找以e为结束的区间

            sum += nums[e];  //先把e收进来

            while(sum>=s){ //大了,看看吧st往右边移动,也就是st++,顺便把sum去掉st的值。

                res = Math.min(res,e-st+1);

                sum -= nums[st++];

            }

        }

        return res == Integer.MAX_VALUE?0:res;

    }

}

59 螺旋矩阵2

首先先定义我们要干什么,我们要画圈。只有一个数字n=1我们要画一个圈,n=3的时候9个数字画2个,n等于5有25个画3个圈。由此可得圈数其实就是n/2+1

 然后怎么画好点呢?每一条边按着箭头画,肯定都遵循左闭右开的原则,开头画完结尾不画。这样画完一个正方形正好不会重复

确定下起点,drawTime表示圈数,每次起点正好是[drawTime,drawTime],第一圈就是[0,0]第二圈是[1,1].第三圈是[2,2]

我们现在设定x轴与y轴。可以看到最右下角那个其实就是[n-1-drawTime,n-1-drawTime],接下来只需让x和y都在[0,n-1-drawTime]之间反复横跳就可以。

 

class Solution {

    public int[][] generateMatrix(int n) {

        int[][] rtn = new int[n][n]; 

        int curr = 1; 

        //画圈。

        for(int drawTime=0;drawTime<=n/2;drawTime++){ 

            //从左到右画,最右边那个不画,此时y固定

            int y= drawTime;

            int x = drawTime;

            for(;x<n-1-drawTime;x++){

                rtn[y][x] = curr ++ ;

            }

            //从上到下画,最下边的不画,此时x轴固定

            x = n -1 -drawTime ;

            for(y=drawTime;y<n-1-drawTime;y++){

                rtn[y][x] = curr ++;

            }

            //从右边往左边画,y轴固定,x变小

            y = n- 1-drawTime;

            for(x=n-1-drawTime;x>drawTime;x--){

                 rtn[y][x] = curr ++;

            }

            //从下面往上画,x固定,y轴变小

            x = drawTime;

            for(y=n-1-drawTime;y>drawTime;y--){

                 rtn[y][x] = curr ++;

            }

        }

        //奇数的话中间还得画一个

        if(n%2!=0){  

            rtn[n/2][n/2] = n * n;

        }

        return rtn;

    }

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值