第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II.

本文介绍了如何高效地计算有序数组的平方值,使用了双指针法替代暴力排序;讨论了如何通过滑动窗口解决长度最小子数组问题;以及如何生成给定大小的螺旋矩阵,包括奇数情况。这些算法都涉及时间复杂度分析。
摘要由CSDN通过智能技术生成

1.有序数组的平方

题目链接:977.有序数组的平方

 1.1上来先来个暴力:

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

1.2看了文章,有更高效的双指针法,学一手

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;
    }
}

 实现过程:

  1. 创建结果数组: 创建一个与输入数组 nums 长度相同的整型数组 result 来存储平方后的结果。

  2. 双指针法:

    • 使用 left 和 right 指针分别指向 nums 数组的开头和结尾。

    • 使用 index 指针指向 result 数组的结尾,用于从后往前填充结果。

  3. 比较平方值:

    • 在每次循环中,比较 nums[left] 和 nums[right] 的平方值。

    • 将较大平方值的元素放置在 result 数组的当前 index 位置,并将相应的指针向内移动。

  4. 填充结果数组:

    • 继续上述步骤,直到 left 和 right 指针相遇或交叉,此时 result 数组已按非递减顺序填充完毕。

  5. 返回结果: 返回填充好的 result 数组。

 2.长度最小的子数组:

题目链接:209.长度最小的子数组

2.1 试水:一开始没仔细看题目,以为是找最小长度,给自己笑拥了,然后试了一下暴力:

暴力out 

1.2滑动窗口:

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不用if
            while (sum >= target) {
                result = Math.min(result, right - left + 1);
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

实现过程:

  1. 初始化变量:

    • left:指向滑动窗口的左边界。

    • sum:滑动窗口中元素的当前总和。

    • minLen:记录符合条件的最小连续子数组的长度,初始值为最大整数。

  2. 滑动窗口:

    • 使用 right 指针不断向右移动,扩大滑动窗口,并将当前元素添加到 sum 中。

  3. 收缩窗口:

    • 当 sum 大于等于 target 时,说明找到了一个符合条件的子数组。

    • 缩小窗口左边界,将 left 指针向右移动,并将对应元素从 sum 中减去。

    • 在缩小窗口的过程中,不断更新 minLen,记录当前的最小长度。

  4. 结果判断:

    • 遍历完数组后,如果 minLen 仍然是最大整数,说明没有找到符合条件的子数组,返回 0。

    • 否则,返回 minLen。

时间复杂度: O(n),因为每个元素最多被访问两次(加入和移出窗口)。

3.螺旋矩阵II

题目链接:59. 螺旋矩阵 II

一上手毫无头绪,只好去看卡哥视频,看完恍然大悟,原来也不是很难

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] nums = new int[n][n];
        int left = 0 , right = 0;
        int end = 1;
        int num = 1;
        int loop = 1;
        int i,j;

        while(loop <= n/2){
            for(j = right ; j < n - end ; j++){
                nums[left][j] = num;
                num++;
            }
            for(i = left ; i < n - end ; i++){
                nums[i][j] = num;
                num++;
            }
            for( ; j > right ; j--){
                nums[i][j] = num;
                num++;
            }
            for( ; i > left ; i--){
                nums[i][j] = num;
                num++;
            }
            left++;
            right++;
            loop++;
            end++;
        }
        if (n % 2 == 1){
            nums[left][right] = num;
        }
        return nums;
    }
}
  1. 初始化: 设置 left 和 right 为 0,end 为 1,num 为 1,loop 为 1。

  2. 循环生成螺旋圈:

    • 使用 while 循环,条件为 loop <= n/2,控制生成螺旋圈的层数。对于奇数 n,最后还需要单独处理中心位置。

    • 在每一层螺旋圈中,进行四次循环,分别填充矩阵的四条边:

      • 从左到右: j 从 right 遍历到 n - end - 1,填充矩阵的顶部行。

      • 从上到下: i 从 left 遍历到 n - end - 1,填充矩阵的右侧列。

      • 从右到左: j 从 n - end - 1 遍历到 right,填充矩阵的底部行。

      • 从下到上: i 从 n - end - 1 遍历到 left,填充矩阵的左侧列。

    • 每次循环后,将 left、right 和 end 各自加 1,将 loop 加 1,进入下一层螺旋圈。

  3. 处理中心位置 (奇数 n): 如果 n 是奇数,最后还需要将数字 num 填入矩阵的中心位置 nums[left][right]。

  4. 返回结果: 返回生成的螺旋矩阵 nums。

时间复杂度: O(n^2),需要遍历整个矩阵。 

  • 24
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值