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

文章介绍了LeetCode上的几个数组处理问题,包括有序数组的平方(使用双指针法按非递减顺序排序),最小长度子数组(利用滑动窗口找到和大于特定值的最小子数组),以及生成螺旋矩阵(通过循环不变量和边界条件处理)。文章强调了在解决数组问题时,考虑排序、滑动窗口和循环不变量等策略的重要性。
摘要由CSDN通过智能技术生成

目录

LeetCode 977.有序数组的平方 

LeetCode 209. 长度最小的子数组

LeetCode 59.螺旋矩阵II 


LeetCode 977.有序数组的平方 

文档讲解:代码随想录

视频讲解:双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

力扣题目:LeetCode 977.有序数组的平方 

题目分析:

  • 非递减顺序排序的整数数组:可以理解为数组中元素包含负数,0,以及正数,且数组元素依次递增但有可能含有相同的元素。
  • 题目要求返回每个数的平方以及按非递减顺序排序:可以得知,我们需要比较一下负数的平方,以及正数的平方,这两种情况下,哪个数值比较大。
  • 因为结果为非递减顺序排序,所以我们可以先把较大的值放到新数组的最后,然后把较大的值的那个下标往后移(或者往前移)

代码如下:

class Solution {
    public int[] sortedSquares(int[] nums) {

        int[] newNums = new int[nums.length];
        int startIndex = 0;
        int endIndex = nums.length - 1;
        int newIndex = nums.length - 1;

        while(startIndex <= endIndex){

            int startRes = nums[startIndex] * nums[startIndex];
            int endRes = nums[endIndex] * nums[endIndex];

            if(startRes > endRes){
                newNums[newIndex] = startRes;
                newIndex--;
                startIndex++;
            }else{
                newNums[newIndex] = endRes;
                newIndex--;
                endIndex--;
            }

        }

        return newNums;
    }
}

                 

思考:

Q:为什么不把平方较小的数值放到数组最前面

A:第一,题目是非递减顺序的数组;第二,题目要求的是按照非递减顺序返回元素的平方值;首先我们需要得到数组的平方值,想要把最小平方的值放在最前面,需要考虑这种特殊情况:就是在含有0元素的情况下,最小平方值的下标就一定是0元素所处的位置。显然要把最小平方值先放在数组前面,需要在考虑两端平方值大小比较的同时,也需要考虑数组中是否有0元素的存在。那么换种思路来想,要返回非递减顺序的平方值,我们既可以按照先把最小平方值放到前面,也可以按照把最大平方值放到最后面,这两种思路都是可以符合题目要求的。我们知道第一种思路在有0的情况下,就会变得较为复杂。而第二种思路,则不需要对0这种情况进行特殊处理。按照非递减顺序的数组,那么最大的值就只可能出现在两端之中,而不可能出现在中间的情况。我们只需要比较数组两端的平方值,哪个比较大,把较大的平方值放在数组的最后即可,然后一个一个往数组前面填,最后数组就会变成非递减顺序的数组。


LeetCode 209. 长度最小的子数组

文档讲解:代码随想录

视频讲解:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili

力扣题目:LeetCode 209. 长度最小的子数组

题目分析: 返回最小子数组的,首先会想到暴力解法,就是用两个for循环,一个for循环作为起始位置,一个for循环作为终止位置,接着判断起始位置到终止位置的子数组是否大于target,大于target返回长度,最后比较哪个子数组的长度大于target的同时长度也最小即可。

参考滑动窗口的代码:代码随想录

class Solution {

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

简单地看了一下思路,实现的过程种还是出现了很多问题。


LeetCode 59.螺旋矩阵II 

文档讲解:代码随想录

视频讲解:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili

力扣题目:力扣

 思路:关键点在于遵循循环不变量的原则,然后处理好拐角的条件,还有就是判断循环的次数。

class Solution {
    public int[][] generateMatrix(int n) {

        int loop = 0;
        int startX = 0;
        int startY = 0;
        int x, y;
        int count = 1;
        int[][] newNums = new int[n][n];

        while(loop++ < n / 2){

            for(x = startX; x < n - loop; x++){
                newNums[startY][x] = count++;
            }

            for(y = startY; y < n - loop; y++){
                newNums[y][x] = count++;
            }

            for(;x > startX; x--){
                newNums[y][x] = count++;
            }

            for(; y > startY; y--){
                newNums[y][x] = count++;
            }

            startX++;
            startY++;
        }

    if(n % 2 != 0){
        newNums[startY][startX] = count;
    }

        return newNums;
    }
}

总结数组常用的算法:

  1. 当数组元素有序且不重复的时候,可以考虑二分查找。
  2. 二分查找的过程中,要注意循环不变量的原则,也就是你的判断条件要是左闭右开的原则,之后的判断的也要遵从左闭右开原则。
  3. 双指针的运用(快慢指针,滑动窗口)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值