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

文章目录

  • 一、977.有序数组的平方
    • 1.暴力排序法
    • 2.双指针法
  • 二、209.长度最小的子数组
    • 1.暴力法
    • 2.滑动窗口法
  • 三、59.螺旋矩阵 II
    • 1.模拟法
  • 总结


一、977.有序数组的平方

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

1.暴力排序法

每个数平方之后排序,也可以称为直接排序法。

  • 时间复杂度: O ( n + n l o g n ) O(n+nlogn) O(n+nlogn)
  • 空间复杂度: O ( l o g n ) O(logn) O(logn)
import java.util.Arrays;
class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] result = new int[nums.length];
        for (int i = 0; i < nums.length; ++i) {
            result[i] = nums[i] * nums[i];
        }
        Arrays.sort(result);
        return result; 
    }
}

2.双指针法

left指向起始位置,right指向终止位置。定义一个新数组result,和A数组一样的大小,让index指向result数组终止位置。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)
class Solution {
    public int[] sortedSquares(int[] nums) {
       int left = 0;
       int right = nums.length - 1;
       int[] result = new int[nums.length];
       int index = nums.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;
           }
       } 
    }
}

注意: 非递减数列是指一个数列中的每个数都不小于前一个数,或者说是递增的,但是可以有相等的情况。原题中提示nums已按 非递减顺序 排序。对于随机数列,暴力排序法更具有通用性。

二、209.长度最小的子数组

题目描述: 给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [ n u m s l , n u m s l + 1 , . . . , n u m s r − 1 , n u m s r ] [nums_{l}, nums_{l+1},..., nums_{r-1}, nums_{r}] [numsl,numsl+1,...,numsr1,numsr],并返回其长度。如果不存在符合条件的子数组,返回 0 。

1.暴力法

两层for循环寻找符号条件的序列

  • 时间复杂度: O ( n 2 ) O(n^{^{2}}) O(n2)
  • 空间复杂度: O ( 1 ) O(1) O(1)

2.滑动窗口法

就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。

  1. 窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
  2. 窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
  3. 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

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

class Solution {
    public int minSubArrayLen(int target, 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>=target ) {
               result = Math.min(result, right - left + 1);
               sum -= nums[left++];
           }
       } 
       return result == Integer.MAX_VALUE ? 0 : result;
    }
}

三、59.螺旋矩阵 II

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

1.模拟法

循环不变量原则,模拟顺时针画矩阵的过程:

  1. 填充上行从左到右
  2. 填充右列从上到下
  3. 填充下行从右到左
  4. 填充左列从下到上

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

class Solution {
    public int[][] generateMatrix(int n) {
        int loop = 0;  // 控制循环次数
        int[][] res = new int[n][n];
        int start = 0;  // 每次循环的开始点(start,start)
        int count = 0;  // 定义填充数字
        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;
    }
}

总结

以上就是今天要学习的内容,相比于暴力解法,双指针法和滑动窗口法时间复杂度更低,模拟法主要掌握模拟的过程。

你可能感兴趣的:(代码随想录算法集训营,算法,矩阵,数据结构,leetcode,java)