力扣刷题|977.有序数组的平方 、209.长度最小的子数组 、59.螺旋矩阵

LeetCode 977.有序数组的平方

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

思路

数组平方的最大值在数组的两端,而且都是向中间逐渐递减的

这里采用双指针法,m指向起始位置,n指向结束位置

定义一个result的新数组大小和原数组相同,k指向数组的末尾

比较m指向的位置和n指向的位置的数据的平方的大小,较大的存入k指向的位置并把该指针向数组中间方向移动

代码实现

public static int[] sortedSquares(int[] nums) {
    int[] result = new int[nums.length];
    int m = 0;
    int n = nums.length - 1;
    int k = n;
    while (m <= n){
        if (Math.pow(nums[m],2) > Math.pow(nums[n],2)){
            result[k--] = (int) Math.pow(nums[m++],2);
        }else {
            result[k--] = (int) Math.pow(nums[n--],2);
        }
    }
    return result;
}

时间复杂度:O(n)

LeetCode 209.长度最小的子数组

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

思路

刚开始我用的是双重循环,代码如下:

public static int minSubArrayLen(int target, int[] nums) {
    int sum = 0;
    int sumLength = nums.length;
    for (int i = 0; i < nums.length; i++) {
        sum = 0;
        for (int j = i; j < nums.length; j++) {
            sum += nums[j];
            if (sum >= target){
                sumLength = (j - i + 1) > sumLength ?  sumLength : j - i + 1;
                break;
            } else if(sum < target && i == 0 && j == nums.length - 1){
                return 0;
            }
        }
    }
    return sumLength;
 }

这种方法最终功能实现是没有问题的,但是耗时比较长,最后提交的结果是超出时间限制,因此下面用另一种方法来解决:滑动窗口

滑动窗口就是不断的调整子序列的开始位置和终止位置得到我们想要的结果
只用一个for循环,循环的索引用窗口的终止位置表示

以题目中的示例来举例,s=7, 数组是 2,3,1,2,4,3,查找的过程:

  • 窗口就是 满足其和 ≥ s 的长度最小的连续子数组

  • 如果当前窗口的值大于s了,窗口就要向前移动了(就是该缩小了)

  • 窗口的结束位置就是遍历数组的指针,也就是for循环里的索引

代码实现

public int minSubArrayLen(int target, int[] nums) {
     int sum = 0;
    int result = Integer.MAX_VALUE;
    int left = 0;
    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;
 }

时间复杂度:O(n)

空间复杂度:O(1)

LeetCode 59.螺旋矩阵

题目链接🔗59.螺旋矩阵

思路

本题是需要遵循循环不变量原则,就是每次要处理的区间是不能变的

模拟顺时针画矩阵的过程:

  • 上侧从左到右

  • 右侧从上到下

  • 下侧从右到左

  • 左侧从下到上

由外向内一圈一圈的画

一圈下来要画四条边,每画一条边都要坚持不变的原则,如左闭右开或者左开右闭,

下面按照左闭右开的原则画:

每一种颜色,代表一条边,坚持了每条边左闭右开的原则

代码实现

public int[][] generateMatrix(int n) {
    int loop = 0;  //循环次数
    int start = 0;  //每次开始循环的结点
    int num = 1;
    int i,j;
    int[][] arr = new int[n][n];
    while (loop++ < n/2){
        //模拟上侧从左到右
        for( j = start;j < n - loop;j++){
            arr[start][j] = num++;
        }

        //模拟右侧从上到下
        for(i = start;i < n - loop;i++){
            arr[i][j] = num++;
        }

        //模拟下侧从右到左
        for(;j >= loop;j--){
            arr[i][j] = num++;
        }

        //模拟左侧从下到上
        for (;i >=loop;i--){
            arr[i][j] = num++;
        }
        start++;
    }
    if ((n % 2) == 1){
        arr[start][start] = num;
    }
    return arr;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值