Day2|977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II

977.有序数组的平方代码随想录

平方后形成凹函数,最大值要么在最左端出现要么在最右端出现,左右指针形成的窗口不断把较大值剔除出窗口,同时赋给新数组。

lass Solution {
    public int[] sortedSquares(int[] nums) {
        int l = 0 , r = nums.length - 1 , k = nums.length - 1;
        int[] res = new int[nums.length];
        while(l <= r){
            if(nums[l]*nums[l] > nums[r]*nums[r]){
                res[k] = nums[l]*nums[l];
                k--;
                l++;
            }else{
                res[k] = nums[r]*nums[r];
                k--;
                r--;
            }
        }
        return res;
    }
}

209.长度最小的子数组代码随想录

第一遍做思路有点混乱,sum收集完相应数组和后没有立即记录子数组长度,而是收缩了窗口,导致子数组长度计算出错

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int l = 0 , r = 0 , sum = 0 , res = Integer.MAX_VALUE;
        while(r < nums.length){
            sum = sum + nums[r];
            while(sum >= target){
                sum = sum - nums[l];
                l++;
                res = Math.min(res , r - l + 1);
            }
            r++;
        }
        return res;
    }
}

 数组和达不到target的情况没考虑

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int l = 0 , r = 0 , sum = 0 , res = Integer.MAX_VALUE;
        while(r < nums.length){
            sum = sum + nums[r];
            while(sum >= target){
                res = Math.min(res , r - l + 1);
                sum = sum - nums[l];
                l++;
            }
            r++;
        }
        return res;
    }
}

最后一次订正: 

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int l = 0 , r = 0 , sum = 0 , res = Integer.MAX_VALUE;
        while(r < nums.length){
            sum = sum + nums[r];
            while(sum >= target){
                res = Math.min(res , r - l + 1);
                sum = sum - nums[l];
                l++;
            }
            r++;
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}

滑动窗口相比暴力省去了一些不必要的比较,在两层循环暴力写法中, i 一个不落的遍历完每一个数组值,同时对于每个 i ,j 都要遍历一遍下标 i 以后的数组值。这种暴力也形成了 i 为左端,j 为右端的窗口,i 遍历完数组,j通过暴力遍历所有右边寻找 i 右边的最短子数组,做到不遗漏。

滑动窗口写法:

前提:非递减顺序 排序的整数数组 nums

窗口里子数组数值和sum >= target分两种情况:

1. 若sum > target,由于窗口左边值较小,左端尝试收缩,以探能否以更短的子数组数值和sum >= target ;

2.若sum恰 = target,窗口不会尝试收缩去寻找更短子数组因为此时本身就是最短的,left前进,right前进,相当于滑动。

这种做法相当于把每一个right左边的满足要求的最短子数组都能找出来,而right遍历完了整个数组,做到了不遗漏。

59.螺旋矩阵II代码随想录

class Solution {
    public int[][] generateMatrix(int n) {
        int i = 0 , j = 0 , loop = n / 2;
        int startRow = 0 , startCol = 0 , count = 1 , offSet = 1;
        int[][] matrix = int[n][n];//代码敲得少new数组都能错
        while(loop--){//while条件得是一个能判断出0或1的表达式,不能是2、3/4之类
            for(j = startCol; j < n - offSet; j++){
                matrix[startRow][j] = count;
                count++;
            }
            for(i = startRow; i < n - offSet; i++){
                matrix[i][j] = count;
                count++;
            }
            for(; j > startCol; j--){
                matrix[i][j] = count;
                count++;
            }
            for(; i > startRow; i--){
                matrix[i][j] = count;
                count++;
            }
            startRow++;
            startCol++;
            offSet++;          
        }
        if(n % 2 == 1){
            matrix[startRow][startCol] = count;
        }
        return matrix;
    }
}

 订正后代码

class Solution {
    public int[][] generateMatrix(int n) {
        int i = 0 , j = 0 , loop = n / 2;
        int startRow = 0 , startCol = 0 , count = 1 , offSet = 1;
        int[][] matrix = new int[n][n];
        while(loop != 0){
            for(j = startCol; j < n - offSet; j++){
                matrix[startRow][j] = count;
                count++;
            }
            for(i = startRow; i < n - offSet; i++){
                matrix[i][j] = count;
                count++;
            }
            for(; j > startCol; j--){
                matrix[i][j] = count;
                count++;
            }
            for(; i > startRow; i--){
                matrix[i][j] = count;
                count++;
            }
            startRow++;
            startCol++;
            offSet++;
            loop--;
        }
        if(n % 2 == 1){
            matrix[startRow][startCol] = count;
        }
        return matrix;
    }
}

每一圈都要用四次循环分别填满4个边,每条边都涉及起始位置判断和终止位置判断。

每行或列的边界处理:留最后一个不填,遵循循环不变量原则。

每填完一圈startCol(填充行元素的起点)和startRow(填充列元素的起点)都要“手动”更新,起点都是闭区间,行尾n - offSet和列尾n - offSet也要“手动”更新,终点都是开区间。

每填完一圈剩余行数或列数-2,填多少圈就看n里有多少二,loop = n / 2 ,n奇数时中间单独空出一个,此时startRow = startCol ,最后单独填进去即可。

 

数组总结:

感觉都在遍历查找填充 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值