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

977.有序数组的平方

文章链接 977

思路:

有序数组存在正负,其平方的最大值必出现在有序数组两端,故用两个指针控制(取)两端的平方值比较后放入新数组最后的非空位置,然后移动指针。

代码:

class Solution {
    public int[] sortedSquares(int[] nums) {
        //存放平方数组
        int[] res = new int[nums.length];
        //新数组的指针
        int index = res.length - 1;
        //原数组的左右指针
        int left = 0, right = nums.length - 1;
        while(left <= right){
            if(nums[left] * nums[left] <= nums[right] * nums[right]){
                res[index] = nums[right] * nums[right];
                index --;
                right --;
            }else{
                res[index] = nums[left] * nums[left];
                index --;
                left ++;
            }
        }
        return res;
    }
}

需要注意的点:

1、取完数对应的指针要移动。

2、新数组从后向前填入(从大到小)。

209.长度最小的子数组

文章链接 209

思路:

使用滑动窗口,右边缘向右一直移动至数组最后,右边缘每移动一次,更新连续子数组的和,当和大于目标值时移动左边缘缩小子数组的长度以寻找最小长度(更新最小长度)

代码:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0;//窗口左边缘
        int sum = 0; 
        int res = Integer.MAX_VALUE;
        int length = 0;
        //right为滑动窗口右边缘
        for(int right = 0; right < nums.length; right++){
            sum += nums[right];
            //当满足条件时控制左边缘,并记录最小长度
            while(sum >= target){
                length = right -left + 1;//满足条件时先记录
                sum -= nums[left++];//更新窗口内的和
                res = Math.min(res,length);//更新最小值
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}

需要注意的点:

1、因为是找最小长度,所以需要遍历完数组。

2、当和满足条件时要用while循环更新滑动窗口左边缘。

3、最后输出结果时要与设置的初始值比较,如果没变说明在滑动窗口移动的过程中没有满足条件的子数组。

59.螺旋矩阵Ⅱ

文章链接 59

思路:

怎样打印(循环)→(拆解)需要一圈一圈顺时针打印→(循环次数)每打印一圈矩阵剩余空白部分的长和宽就-2,故需要循环n/2圈

每一次的循环中需要怎么样遍历每一条边→(拆解)顺序为上右下左,注意控制边界条件,每一条边最后一个位置不取(左闭右开)留给下一个方向的遍历

最后注意当n为奇数时,最中心的空白需单独补充

代码:

class Solution {
    public int[][] generateMatrix(int n) {
        int loop = 0;//控制循环的次数
        int count = 1;//需要打印的数字
        int start = 0;//控制每一次(圈)打印的起始位置(start,start)
        int[][] res = new int[n][n];
        int i,j;//设置i、j为全局变量,原因:在同一圈的遍历中i、j需要连续使用
        while(loop++ < n/2){//每转一圈长和宽减少2,所以循环n/2次,判断后从1开始计数
            //上
            for(j = start; j < n - loop; j++){
                res[start][j] = count++;
            }
            //右
            for(i = start; i < n - loop; i++){
                res[i][j] = count++;
            }
            //下
            for(;j > start; j--){//j的值从上面的循环传递下来,不用管初始值
                res[i][j] = count++;
            }
            //左
            for(; i > start; i--){
                res[i][j] = count++;
            }
            start++;//打印完一圈后更新初始位置
        }
        if(n % 2 == 1){//如果n为奇数,中心位置需要填充
            res[start][start] = count;
        }  
        return res;  
    }
}

需要注意的点:

1、每打印一圈起始位置会改变,故需要设置变量(start)控制起始位置。

2、要想到采用什么规律推进打印(循环)→一圈一圈进行,圈数为n/2、

3、奇数单独考虑最中心位置。

4、打印的位置i、j连续使用,所以需要提前定义为全局变量。

5、注意打印的终止点为开区间(将最后一个点留给下一个方向打印)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值