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

基础知识

Integer.MAX_VALUE

java int 类整数的最大值是 2 的 31 次方 - 1 = 2147483648 - 1 = 2147483647

可以用 Integer.MAX_VALUE 表示int 类整数的最大值

Integer.MAX_VALUE + 1 = Integer.MIN_VALUE = -2147483648

Math.min()

Java Math 类提供了min函数,用于返回两个数字中的较小值。

  • 该函数接受两个参数,可以是任何整数类型或浮点类型,包括byte、short、int、long、float和double。
  • 如果第一个参数小于第二个参数,则返回第一个参数;否则返回第二个参数。如果两个参数相等,则返回其中任意一个。
  • 如果参数是NaN(不是数字),则返回NaN。如果没有参数,结果为Infinity(无穷大)。

 注意:没有参数时,Math.min()比Math.max()大

Math.max() 返回给定的一组数字中的最大值。如果给定的参数中至少有一个参数无法被转换成数字,则会返回 NaN。如果没有参数,则结果为 - Infinity。

刷题

977.有序数组的平方

题目链接 | 文章讲解 | 视频讲解

题目:给你一个按非递减顺序排序的整数数组 nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。

示例 :

  • 输入:nums = [-4,-1,0,3,10]
  • 输出:[0,1,9,16,100]
  • 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]

难点:数组是有序的, 但可能负数平方之后可能成为最大数了。

思路:数组平方的最大值就在数组的两端,不可能是中间。可以考虑双指针法了,i指向起始位置,j指向终止位置。定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。 

  • 如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。
  • 如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i]; 。

代码随想录算法训练营 | day2 977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II_第1张图片

代码如下:

class Solution {
    public int[] sortedSquares(int[] nums) {
        int right = nums.length - 1;
        int left = 0;
        int[] result = new int[nums.length];
        int index = result.length - 1;
        while (left <= right) {
            if (nums[left] * nums[left] > nums[right] * nums[right]) {
                // 正数的相对位置是不变的, 需要调整的是负数平方后的相对位置
                result[index--] = nums[left] * nums[left];
                ++left;
            } else {
                result[index--] = nums[right] * nums[right];
                --right;
            }
        }
        return result;
    }
}

 209.长度最小的子数组

题目链接 | 文章讲解 | 视频讲解

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

示例:

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

难点:如何降低空间复杂度?最直白的方法就是两层 for 循环,将数组 nums 中的每个下标作为子数组的开始下标,对于每个开始下标 i,需要找到大于或等于 i 的最小下标 j,使得从 nums[i] 到 nums[j] 的元素和大于或等于 s,并更新子数组的最小长度。

思路:采用滑动窗口的方法。

滑动窗口

  • 定义两个指针 start 和 end 分别表示子数组(滑动窗口窗口)的开始位置和结束位置,维护变量 sum 存储子数组中的元素和(即从 nums[start] 到 nums[end] 的元素和)。
  • 初始状态下,start 和 end 都指向下标 0,sum 的值为 0。
  • 每一轮迭代,将 nums[end] 加到 sum,如果 sum≥s ,则更新子数组的最小长度(此时子数组的长度是 end−start+1,然后将 nums[start] 从 sum 中减去并将 start 右移,直到 sum

代码随想录算法训练营 | day2 977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II_第2张图片

代码如下:

class Solution {

    // 滑动窗口
    public int minSubArrayLen(int s, int[] nums) {
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= s) {
                result = Math.min(result, right - left + 1);
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

这里我在写代码时,result初始赋值为length + 1,因为子序列长度肯定不会超过length,也可用于判断有无符合条件的子数组。看了参考代码后,get了新知识:Integer.MAX_VALUE。

59.螺旋矩阵II

题目链接 | 文章讲解 | 视频讲解 

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

示例:

输入: 3

输出: [ [ 1, 2, 3 ],

           [ 8, 9, 4 ],

           [ 7, 6, 5 ] ]

代码随想录算法训练营 | day2 977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II_第3张图片

代码如下:

class Solution {
    public int[][] generateMatrix(int n) {
        int loop = 0;  // 控制循环次数
        int[][] res = new int[n][n];
        int start = 0;  // 每次循环的开始点(start, start)
        int count = 1;  // 定义填充数字
        int i, j;

        while (loop++ < n / 2) { // 判断边界后,loop从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 >= loop; j--) {
                res[i][j] = count++;
            }

            // 模拟左侧从下到上
            for (; i >= loop; i--) {
                res[i][j] = count++;
            }
            start++;
        }

        if (n % 2 == 1) {
            res[start][start] = count;
        }

        return res;
    }
}

 学习总结

感觉跟着画一遍算法流程,思路就差不多理清了,然后再理解初始赋值及每个边界条件。 

你可能感兴趣的:(java刷题记录,矩阵,算法,java,排序算法,leetcode)