代码随想录算法训练营第二天 | 977、209、59

文章介绍了三个算法问题的解决方案:1)有序数组的平方,通过双指针处理正负数情况得到非递减平方数组;2)长度最小的子数组,使用滑动窗口找到和大于等于目标值的最小子数组;3)螺旋矩阵II,模拟生成过程,按螺旋顺序填充矩阵元素。

代码随想录算法训练营第二天 | 977、209、59

977.有序数组的平方

题目描述

给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
示例1:
输入:nums=[−4,−1,0,3,10]nums = [-4,-1,0,3,10]nums=[4,1,0,3,10]
输出:[0,1,9,16,100][0,1,9,16,100][0,1,9,16,100]
示例1:
输入:nums=[−7,−3,2,3,11]nums = [-7,-3,2,3,11]nums=[7,3,2,3,11]
输出:[4,9,9,49,121][4,9,9,49,121][4,9,9,49,121]

思路

题目中非递减顺序排序的整数数组,生成的新数组也要按照非递减顺序排序。在本题中,针对结果来讲,给出的数组是两段或一段有序的数组。若数组中全部为正整数,则平方数组为非递减顺序;若数组中全部为负整数,则平方数组为非递增顺序;若同时存在负整数和正整数,则平方数组在0之前为非递增,在0之后为非递减顺序。
那么首先,需要对不同情况分类讨论;
针对同时存在负整数和正整数的情况,使用双指针的方式进行比较,并根据大小关系来判断其位置。

解法

class Solution {
    public int[] sortedSquares(int[] nums) {
        int neg = -1;
        int n= nums.length;
        for(int i=0;i<n;i++){
            if(nums[i]<0){
                neg = i;
            }
            else{
                break;
            }
        }
        int i=neg,j=neg+1;
        int[] ans = new int[n];
        int index = 0;
        while(i>=0 || j<n){
            if(i<0){
                ans[index++] = nums[j]*nums[j];
                j++;
            }
            else if(j == n){
                ans[index++] = nums[i]*nums[i];
                i--;
            }
            else if(nums[i]*nums[i] > nums[j]*nums[j]){
                ans[index++] = nums[j]*nums[j];
                j++;
            }
            else{
                ans[index++] = nums[i]*nums[i];
                i--;
            }

        }
        return ans;
    }
}

总结

1、注意分类讨论,全是正整数或负整数的情况可以先行判断。
2、对于有正有负的情况,注意找到分界点并使用双指针在分界点两侧移动寻找相等。

209. 长度最小的子数组

题目描述

给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例1:
输入:target=7,nums=[2,3,1,2,4,3]target = 7, nums = [2,3,1,2,4,3]target=7,nums=[2,3,1,2,4,3]
输出:222
示例2:
输入:target=4,nums=[1,4,4]target = 4, nums = [1,4,4]target=4,nums=[1,4,4]
输出:111
示例3:
输入:target=11,nums=[1,1,1,1,1,1,1,1]target = 11, nums = [1,1,1,1,1,1,1,1]target=11,nums=[1,1,1,1,1,1,1,1]
输出:000

思路

题目要求找到和大于等于目标值的长度最小连续子数组,则能够想到使用滑动窗口的方法。
在滑动窗口中,右边界扩张,左边界撤销。

解法

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

总结

本题中最重要的是能够看出应该使用滑动窗口求解。但在对滑窗的应用上并没有太多的坑,只需按部就班即可。

59. 螺旋矩阵Ⅱ

题目描述

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例1:
输入:n=3n=3n=3
输出:[[1,2,3],[8,9,4],[7,6,5]][[1,2,3],[8,9,4],[7,6,5]][[1,2,3],[8,9,4],[7,6,5]]
示例2:
输入:n=1n=1n=1
输出:[[1]][[1]][[1]]

思路

本题在总体思路上很简单,只需模拟生成过程,一圈一圈地放置元素即可。但在细节思路上,会发现有很多需要注意的问题,首要的就是每一行每一列在填充时的规则,是左闭右闭、左闭右开还是左开右闭。这里我选择的是左闭右开原则,不仅可以从原始位置开始便利,而且在行和列的角度上更具有对称感。

解法

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

总结

对于本题来说,最重要的是要能够明确遍历时的规则,约定好每一行每一列在循环时的边界范围。此外,还有一个需要注意的点是,是否需要补充最中心的元素,在本题前两次的提交中我就忘记了这个而导致错误。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值