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

文章详细介绍了如何利用双指针解决有序数组的平方问题,以及滑动窗口在寻找最小子数组长度中的应用。此外,还展示了生成螺旋矩阵的算法,强调了循环不变量原则和边界条件的处理。每道题目都提供了Java代码实现,并讨论了时间复杂度和空间复杂度。
摘要由CSDN通过智能技术生成

977.有序数组的平方

题目链接

思路:首先知道该数组为非递减数组,因此在平方后该数组是两边大,中间小的趋势。因此采用双指针解法

1.左右指针分别指向数组的第一个数和最后一个数,循环比较直至left > right。

2.每次比较将较大的数逆序更新至新数组,同时指向新数组的指针向前移动一位

3.最终返回一个平方后的非递减数组

注意:该题考虑到双指针解法即可解决。

java代码如下:时间复杂度O(n)  空间复杂度O(1)

public int[] sortedSquares(int[] nums) {
        //新数组
        int[] newLength = new int[nums.length];
        //左右指针
        int left = 0;
        int right = nums.length - 1;
        //定义一个新变量负责新数组的更新
        int index = right;
        while (left <= right) {//这里while的条件还存在问题
            //这里left  <= right的原因是保证遍历到每个元素,如果是<的话,会缺失一个元素
            //逻辑:较大的数更新至数组
            if (nums[right] * nums[right] > nums[left] * nums[left]) {
                newLength[index--] = nums[right] * nums[right];
                right--;
            }else {
                newLength[index--] = nums[left] * nums[left];
                left++;
            }
        }
        return newLength;

    }

209.长度最小的子数组

题目链接

思路:

1.外层for循环遍历整个数组,定义为终止位置(若将外层for循环定义为初始位置,则可采用暴力解法,枚举所有子数组情况更新即可)。

2.记录当前遍历所有值的和,若大于目标值,移动初始位置。

3.移动初始位置前,记录当前子数组长度并更新。

注意:该题较为由双指针体现的滑动窗口思想。滑动窗口的终止位置的定义以及初始位置的移动非常关键!

代码如下:

public int minSubArrayLen(int target, int[] nums) {
        //记录总和
        int sum = 0;
        //记录当前子数组长度
        int subL = 0;
        int result = Integer.MAX_VALUE;
        //起始位置
        int j = 0;
        //控制终止位置
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            while (sum >= target) {
                //此时总和大于目标值 记录当前长度
                subL = i - j + 1;
                //更新长度
                result = Math.min(result, subL);
                sum -= nums[j];
                j++;
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }

59.螺旋矩阵II

题目链接

思路:

1.首先考虑的是循环圈数,应为n / 2。并且考虑到矩阵行列为奇数,填充中间的值

2.进入圈中,考虑每边的循环次数(坚持循环不变量原则),即每边的循环方式保持一致即可。

3.没圈结束,进入到下一个圈,此时起始位置改变,每边的循环次数也随之改变,保持每个大圈相同即可。

注意:该题主要考察对代码的掌握能力,同时保持每一圈的添加方式一致即可

代码如下:

public static int[][] generateMatrix(int n) {
        //定义初始变量
        int start = 0;
        int loop = n / 2;
        //定义矩阵的长宽

        //控制每边添加数
        int offset = 1;
        //定义所添加的数和新数组
        int count = 1;
        int[][] arr = new int[n][n];
        //控制转圈-循环次数
        while (loop-- > 0) {
            int i,j;
            //第一条边
            for (j = start; j < n - offset; j++) {
                arr[start][j] = count++;
            }
            //第二条边
            for (i = start; i < n - offset; i++) {
                arr[i][j] = count++;
            }
            //第三条边
            for (;j > start; j--) {
                arr[i][j] = count++;
            }
            //第四条边
            for (;i > start; i--) {
                arr[i][j] = count++;
            }
            //首圈完毕
            start++;
            offset++;
        }
        //奇数单独赋值
        if (n % 2 == 1){
            arr[loop][loop] = count;
        }
        return arr;
    }

总结:

这两天的学习完成了代码随想录的数组模块。所学知识如下:

二分查找

搜索数组中的某个数,使用双指针对整个区间进行二分,满足不同的条件是更新左边界或者右边界。最终找到该值。

注意:此时对二分区间的不同定义也会影响着更新区间的方式,只要整个循环过程中保持二分区间的一致定义即可轻松解决该题。

双指针

该题体现的是快慢指针思想,我们需弄清楚快慢指针的定义即可(快指针寻找非目标值,即需要更新的元素。慢指针定义为更新元素的索引)。

注意:通过快慢指针在1个for循环里完成两个for循环所完成的任务

滑动窗口

该题也是采用双指针做法,定义终止位置,在判断是否满足条件。从而确定起始位置的走向。

注意:该题主要考虑滑动窗口的起始和终止位置,以及滑动窗口的移动。

模拟法

该题并无太多算法,需要确定的是在遍历每个大圈是,遍历规则保持一致,及循环不变量原则。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值