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

977.有序数组的平方

题目链接:977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
首先,可以直接使用暴力法解决,即先平方后排序
具体代码如下:

public int[] sortedSquares(int[] nums) {
        for(int fast=0;fast<nums.length;fast++){
            nums[fast]=nums[fast]*nums[fast];
        }
        for(int fast=0;fast<nums.length;fast++){
            for(int slow=fast;slow<nums.length;slow++){
                if(nums[fast]>nums[slow]){
                int temp=nums[fast];
                nums[fast]=nums[slow];
                nums[slow]=temp;
            }}

        }
        return nums;
    }

另一种方式是双指针法
具体思路如下:结合这道题目的特征,一个同时包含正数负数的递增数组,平方之后,其最小值一定在中间的某个位置,或者在首位(这种情况都是正数,可以直接平方后输出)
那么,使用两个指针,一个指向首个元素,一个指向末位元素,每次将两者平方的最大值放入数组最末端即可(题目要求从小到大排列)

 public int[] sortedSquares(int[] nums) {
        int[] result=new int[nums.length];
        int index=nums.length-1;//result数组中当前元素的位置
        int left=0;
        int right=nums.length-1;
        while(left<=right){
            if(nums[left]*nums[left]>=nums[right]*nums[right]){
                result[index]=nums[left]*nums[left];
                left++;
                index--;
            }else{
                result[index]=nums[right]*nums[right];
                right--;
                index--;
            }
        }
        return result;
    }

209.长度最小的子数组(!注意代码整洁性)

题目链接:长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

解题思路:滑动窗口解法
滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果
实现滑动窗口,主要确定如下三点:
窗口内是什么?
如何移动窗口的起始位置?
如何移动窗口的结束位置?

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
我的解法中的循环不包含第一次寻找窗口的过程,虽然可以通过但代码繁琐
具体代码如下

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left=0;
        int right=0;
        int sum=nums[left];
        while(sum<target&&right<nums.length-1){
            right++;
            sum+=nums[right];
        }
        if(right==nums.length-1&&sum<target){
            return 0;
        }
        if(right==nums.length-1&&sum>target){
            while(sum-nums[left]>=target){
                sum=sum-nums[left];
                left++;
            }
        }
        int result=right-left+1;
        while(right<nums.length-1){
            right++;
            sum=sum+nums[right];
            while(sum-nums[left]>=target){
                sum=sum-nums[left];
                left++;
            if(right-left+1<result){
                result=right-left+1;
            }
        
        }
        return result;
    }
}

为了统一一次寻找窗口的过程
首先将目标值设为Integer.MAX_VALUE,因为本题的目标是求解最小值。
其次,right数组对下标的遍历贯穿始终,所以可以统一,上面的第一种将遍历分为了两段。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left=0;
        int right=0;
        int sum=0;
        int result= Integer.MAX_VALUE;
        for(right=0;right<=nums.length-1;right++){
            sum+=nums[right];
            while(sum>=target){
                //每次缩圈前更新result值,保证最值最新
                result = Math.min(result, right - left + 1);
                //缩圈
                sum -= nums[left++];
            }
        }
        return result==Integer.MAX_VALUE?0:result;
    }
}

相关题:水果成蓝

59.螺旋矩阵II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
解题思路:不断控制边界填数即可

class Solution {
    //指定边界循环
    public int[][] generateMatrix(int n) {
        int top=0;
        int bottom=n-1;
        int left=0;
        int right=n-1;
        int now=1;
        int[][] result=new int[n][n];
        //->
        while(now<=n*n){
            for(int i=left;i<=right;i++){
                result[top][i]=now;
                now++;
            }
            top++;
            for(int i=top;i<=bottom;i++){
                result[i][right]=now;
                now++;
            }
            right--;
            for(int i=right;i>=left;i--){
                result[bottom][i]=now;
                now++;
            }
            bottom--;
            for(int i=bottom;i>=top;i--){
                result[i][left]=now;
                now++;
            }
            left++;
        }
        return result;
    }
}

相关题目:螺旋矩阵

你可能感兴趣的:(代码随想录,矩阵)