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

LeetCode 977 有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
视频讲解:https://www.bilibili.com/video/BV1QB4y1D7ep

题目描述:给你一个按非递减顺序 排序的整数数组 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]

双指针法

思路:由于数组是非递减顺序,因此数组元素的最大值在两端取得,可用双指针法解决,定义left,right分别指向左右两个位置,比较后将数组中值大的元素存放到新数组下标大的位置。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] arr = new int [nums.length];//定义一个新数组,大小和nums相等
        int left = 0,right = nums.length - 1;
        int length = nums.length - 1;
        for(;left <= right;){
            if(nums[left] * nums[left] > nums[right] * nums[right]){
                arr[length--] = nums[left] * nums[left];
                left++;
            }else{
                arr[length--] = nums[right] * nums[right];
                right--;
            }
        }
        return arr;
    }
}

LeetCode 209 长度最小的子数组

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
视频链接:https://www.bilibili.com/video/BV1tZ4y1q7XE

题目描述:给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例2:
输入:target = 4, nums = [1,4,4]
输出:1

示例3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

解法1:暴力解法

思路:直接两层for循环寻找符号条件的子序列(LeetCode上超出时间限制了)

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int result = Integer.MAX_VALUE;
        int sum = 0;
        int subL = 0;//子序列长度
        for(int i = 0; i < nums.length; i++){
            sum = 0;
            for(int j = i; j < nums.length; j++){
                sum += nums[j];
                if(sum >= target){
                    subL = j - i + 1;
                    result = result < subL ? result : subL;
                    break;
                }
            }           
        }
        return result == Integer.MAX_VALUE ? 0 : result; 
    }
}

解法2:滑动窗口法

思路:滑动窗口主要是不断的调节子序列的起始位置和终止位置,来获取想要的结果。滑动窗口采用一层for循环解决问题,其中的关键问题是for循环的索引是起始位置还是终止位置。如果是起始位置,就和暴力解法的原理差不多,要用一层for循环解决,则索引位置要为终止位置,然后在满足>=target时移动起始位置。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int begin =0, sum = 0;//begin为起始位置
        int result = Integer.MAX_VALUE;//最终结果,初始值设为整形类型范围的最大值
        for(int end = 0; end < nums.length; end++){//end为终止位置
            sum += nums[end];//将区间内的元素相加
            while(sum >= target){
                result = Math.min(result, end - begin + 1);//更新长度,保证长度最小
                sum = sum - nums[begin];
                begin++;
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;//处理所有元素之和也不满足的情况
    }
}

LeetCode 59 螺旋矩阵II

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
视频链接:https://www.bilibili.com/video/BV1SL4y1N7mV/

题目描述:给你一个正整数 n ,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例1:
代码随想录算法训练营day02| LeetCode 977 有序数组的平方 、LeetCode 209 长度最小的子数组 、LeetCode 59 螺旋矩阵II_第1张图片
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例2:
输入:n = 1
输出:[[1]]

思路:解答本题要坚持循环不变量原则,该题边界非常多,要理清边界条件,就要坚持同一种规则来模拟四条边,例如都采用左闭右开原则

class Solution {
    public int[][] generateMatrix(int n) {
        int startx = 0, starty = 0;
        int[][] arr = new int [n][n];
        int loop = 0;//控制循环次数
        int count = 1;// 定义填充数字
        int i, j;
        while(loop++ < n/2){
            // 模拟上侧从左到右
            for(j = starty; j < n - loop; j++){
                arr[startx][j] = count++;
            }
            // 模拟右侧从上到下
            for(i = startx; i < n - loop; i++){
                arr[i][j] = count++;
            }
            // 模拟下侧从右到左
            for(; j > starty; j--){
                arr[i][j] = count++;
            }
            // 模拟左侧从下到上
            for(; i > startx; i--){
                arr[i][j] = count++;
            }
            startx++;// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
            starty++;
            loop++;
        }
        if(n % 2 == 1){//当n为奇数时,最中心的点要单独赋值
            arr[startx][starty] = count;
        }
        return arr;
    }
}

总结

今天完成了与数组有关的基础题,Carl哥这几道经典数组题给我展示了解决这类题的几种思想(二分法、双指针发、滑动窗口、模拟行为),之后我也会将与数组相关的其他题目完成。

你可能感兴趣的:(算法,leetcode,矩阵)