Day02 算法训练 977.有序数组的平方 | 209.长度最小的子数组 | 59.螺旋矩阵


自用,记下思路,欢迎提供更好的思路和建议。

977.有序数组的平方

  • 977.有序数组的平方 | 题目链接
  • 思路
    1. 数组是有序的。
    2. 最大值一定在数组的两端之一的值取到,所以定义两个指针(一左一右),不断向中间滑动,其间一直比较元素平方后的大小。
  • 注意
    1. 需定义一个新的数组存放平方后的元素
    2. 往新数组里存放元素是从最大值开始的,也就是从下表length-1开始的,往前存,越往前的值越小。
  • 时间复杂度O(n)
  • 空间复杂度(貌似有争议 有说O(1) 有说O(n)):暂时还不太懂这个,后续补充学习。
class Solution {
    public int[] sortedSquares(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        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++]; //存放元素后,新数组的索引往前走index--;相应的left往右走left++
            } else {
                result[index--] = nums[right] * nums[right--];
            }
        }
        return result;
    }
}

209. 长度最小的子数组

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

  • 思路:两个指针,滑动窗口。

    1. 快指针往前移动,期间不断计算累加值,当累加值满足要求(sum>target)后,可以操作慢指针向前移动,以找到长度最小的子数组。
    2. 减去慢指针一开始指向的值,慢指针向后移动,看此时的快慢指针之间的元素和还是否满足要求。
    3. 如果依然满足,就继续while循环,sum减去慢指针此时指向的元素,慢指针又向后移动,看此时是否满足要求。以此类推。
    4. 直至不满足要求后,停止满指针的移动,继续移动快指针(外层for循环中的内容)。
  • 注意:

    1. 一开始定义一个result为整型的最大值,如果没有满足要求的子数组,则用三元判断返回0。
    2. 如果有满足的子数组,就取子数组的长度(fast - slow + 1)和result作比较。
  • 时间复杂度O(n)

  • 空间复杂度O(1)

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int slow = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE; //定义个最大值用于作比较

        for(int fast = 0; fast < nums.length; fast++) {
            sum += nums[fast];
            while(sum >= target) {
                result = Math.min(result, fast - slow +  1); //有满足要求的数据就更新result的值
                sum -= nums[slow++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result; //三元运算符
    } 
}

59. 螺旋数组

答案是力扣中精选答案第一个,放上链接大神解法
在这里插入图片描述

  • 一些我写代码的碎碎念。。。。
class Solution {
    public int[][] generateMatrix(int n) {
        //定义4个边界
        int left = 0, right = n - 1, top = 0, bottom = n - 1;
        //定义新数组
        int[][] res = new int[n][n];
        //定义填入的数值
        int num = 1;

        while(num <= n*n) {
            //先填充上边的一行,此时横坐标不变为top,纵坐标一直改变,一直往右走,一直加。
            for(int i = left; i <= right; i++) {
                res[top][i] = num++;
            }
            //上边一行填充完了,top往下移,加一。
            top++;

            //填充右边一列,此时纵坐标不变为right,横坐标从top开始一直往下走,一直加。
            for(int i = top; i <= bottom; i++) {
                res[i][right] = num++;
            }
            //右边的一列填充完毕,right左移,减一。
            right--;

            //填充下边一行,横坐标不变为bottom,纵坐标从right往左走,一直减。
            for(int i = right; i >= left; i--) {
                res[bottom][i] = num++;
            }
            //下边一列填充完毕,bottom上移,减一。
            bottom--;

            //填充左边一列,纵坐标不变为left,横坐标从bottom往上移,一直减。
            for(int i = bottom; i >= top; i--) {
                res[i][left] = num++;
            }
            //左边一列填充完毕,left右移,加一。
            left++;
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuwuuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值