day2 | 977.有序数组的平方 、209.长度最小的子数组 、59.螺旋矩阵II

题目链接:977. 有序数组的平方 - 力扣(LeetCode)

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

解题思路:

  • 暴力解法

  时间复杂度为 O(n+nlogn)

  将数组中的元素先平方后排序

class Solution {
    public int[] sortedSquares(int[] nums) {
        for(int i =0 ;i<nums.length;i++){
            nums[i] *=nums[i];
        }
        Arrays.sort(nums);
        return nums;
    }
}

  这里直接用到java自带的对数组进行排序的排序函数 Arrays.sort()

  • 双指针法

  时间复杂度为 O(n)

  因为所给的数组是非递减的,考虑到数组中可能存在负值的情况所以最大值只能在数组的两端取到,分别定义 i 和 j 指向数组的两端。

  创建一个新数组 result 保存结果,r 指向 result 数组的最后一个元素。

  比较 array[i] 和 array[j] 的大小,较大值填入 r 所指的位置。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int l=nums.length;
        int r=l-1;
        int[] result=new int[l];
        int i=0,j=r;
        while(i<=j){
            if(Math.abs(nums[i]) >= Math.abs(nums[j])){
                result[r]=nums[i]*nums[i];
                r--;
                i++;
            }
            else{
                result[r]=nums[j]*nums[j];
                r--;
                j--;
            }
        }
        return result;
    }
}

 

题目链接:209. 长度最小的子数组 - 力扣(LeetCode)

题目描述:找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

解题思路:

  • 暴力求解法

  时间复杂度 O(n^2)

  使用两层 for 循环进行求解。

 1 class Solution {
 2     public int minSubArrayLen(int target, int[] nums) {
 3         int result = Integer.MAX_VALUE; //int的最大值
 4         int sum=0;
 5         int l=0;
 6         for(int i=0;i<nums.length;i++){
 7             sum = 0;
 8             for(int j=i;j<nums.length;j++){
 9                 sum+=nums[j];
10                 if(sum>=target){
11                     l=j-i+1;
12                     result = l<=result?l:result;
13                     break;
14                 }
15             }
16         }
17         return result==Integer.MAX_VALUE?0:result; //若result的值为Integer.MAX_VALUE就表示result未被赋值
18     }
19 }
  • 滑动窗口

  时间复杂度

  所谓的滑动窗口,就是不断调节子序列的起始位置和终止位置,从而得出我们想要的结果。在暴力求解中,第一层 for 循环表示滑动窗口的起始位置,第二层 for 循环表示滑动窗口的终止位置。滑动窗口就是用一个 for 循环来实现两个 for 循环实现的区间搜索。

  在本题中实现滑动窗口,主要确定如下三点:

  • 窗口是什么?

  在本题中窗口就是 满足其和 ≥ target 的长度最小的连续子数组

  • 如何移动窗口的起始位置?

  如果当前窗口的值 ≥ target 窗口就应该向前移动(缩小窗口)

  • 如何移动窗口的终止位置?

  实现对数组的遍历。

 1 class Solution {
 2     public int minSubArrayLen(int target, int[] nums) {
 3     int sum = 0;//子序列的和
 4     int j=0;
 5     int result = Integer.MAX_VALUE;
 6     for (int i=0;i<nums.length;i++){
 7         sum += nums[i];
 8         while(sum >= target){
 9             result = Math.min(result,i-j+1);
10             sum -= nums[j];
11             j++;
12         }
13     }
14     return result == Integer.MAX_VALUE ? 0 : result;
15 }
16 }

 

题目链接:59. 螺旋矩阵 II - 力扣(LeetCode)

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

解题思路:

  对每一圈进行一个遍历。

 1 class Solution {
 2     public int[][] generateMatrix(int n) {
 3       int startx=0,starty=0;//每圈 每行/列 的起始位置
 4       int offset=1;//实现每圈 每行/列 的终止位置(每行都是左闭右开的区间)
 5       int loop=0;
 6       int count=1;//填充螺旋矩阵的值
 7       int[][] a=new int[n][n];//创建二维数组
 8       int i,j;
 9       int mid=n/2;
10       while(loop++ < n/2){
11           i=startx;
12           j=starty;
13           for(;j<n-offset;j++){
14             a[i][j]=count++;
15           }//上侧从左至右
16           for(;i<n-offset;i++){
17               a[i][j]=count++;
18           }//右侧从上至下
19           for(;j>starty;j--){
20               a[i][j]=count++;
21           }//下侧从右至左
22           for(;i>startx;i--){
23               a[i][j]=count++;
24           }//左侧从下至上
25           startx++;
26           starty++;
27           offset++;
28       }
29       if(n%2==1){
30           a[mid][mid]=count;
31       }
32       return a;                                  
33     }
34 }

 

posted @ 2023-01-14 16:33  Inbreak  阅读(19)  评论(0)    收藏  举报