文章目录
Day2
一、977.有序数组的平方
1. 思路分析
为什么原数组顺序被打破?因为负数平方后会变为正数。
第一想法:比较繁琐。要先找到正负数的中间值,然后双指针依次往两边找,取平方值小的加入新数组。最后哪边未录入,便直接全部平方后加入新数组。步骤像极了归并排序。
优化思路:向新数组填入数据的过程,也不一定非要从左向右。实际上,可以从右向左,从大到小。而现有元素平方的最大值,不是在头,便是在尾。如此,我们无需费力找到正负数的分界线,更无需多确立那么多边界条件。
2. 解法分析
- 开辟一个新数组,索引指向尾部。
- 两个指针指向旧数组,一头一尾,比较二者平方后的大小。
- 索引指针的值 = 平方后较大的值。同时平方后数值较大的指针向中间进一位。
- 循环的的终止条件利用了索引指针。当新数组全部填充完毕时终止循环。
3. 代码展示
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0, right = nums.length - 1;
int[] nums2 = new int[nums.length];
for (int index = nums.length - 1; index >= 0; index--) {
if (nums[left] * nums[left] >= nums[right] * nums[right]) {
nums2[index] = nums[left] * nums[left];
left++;
}
else{
nums2[index] = nums[right] * nums[right];
right--;
}
}
return nums2;
}
}
二、209.长度最小的子数组
1. 思路分析(滑动窗口法)
这真的是一个非常巧妙的解题思路。
暴力解法:无需多言,两个for循环,n平方的时间复杂度,因时长过长,无法在LeetCode上提交。
滑动窗口法:所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
通过不断调整框中的内容,右指针右移来补充元素,左指针右移来删除元素。在框中元素和大于等于目标值时统计当前窗口长度。
2. 解法分析
实现该方法要明确以下问题?
- 窗口里是什么?
- 什么时候移动窗口结束位置?
- 什么时候移动窗口起始位置?
- 窗口中的便是连续子数组。而我们要找的,就是长度最小、且满足元素和大于等于目标值的窗口。
- 移动窗口结束位置:只要窗口数据和小于目标值,就向后移动扩大窗口,直至数据和大于等于。
- 移动窗口起始位置:窗口数据和大于等于目标值时,我们便需要缩减窗口来寻求最小的长度。每次检定“窗口数据和大于等于目标值”成功,便与当前最小长度比较一次,同时缩减一次窗口。
3. 注意事项
- 同在每个起点都遍历一遍的暴力解法相比,滑动窗口法动态地通过终点去找起点,避免了很多无效运算,达成O(n)的时间复杂度。
- 方法精髓:将数组的遍历索引当做窗口的结束位置,以其为参考动态地调节窗口起始位置。
4. 代码展示
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i = 0;
int sum = 0;
int result = nums.length + 1;
for(int j = 0; j < nums.length; j++) {
sum += nums[j];
while(sum >= target) {
result = Math.min(result, j - i + 1);
sum -= nums[i++];
}
}
return i == 0 ? 0 : result;
}
}
三、59.螺旋矩阵II
1. 思路分析
本题不涉及什么算法。但是对矩阵的模拟过程,讲求对区间精准而又规律的划分、对边界条件的头脑清晰。
找到一般规律,以避免过多的边界条件。
按顺时针顺序螺旋排列元素,使其构成一正方形矩阵。
那么按照元素从小到大的顺序,对这个矩阵中的一圈的填充就应该是:从左到右、从上到下、从右到左、从下到上。
那么如何找到合适的区间呢?左闭右开我比较习惯。关键是要确保每一条线的填充都是按照相同的规则进行。
2. 解法分析
- 确定每一条线的的位置所在:固定在哪行或哪列?填充顺序如何?区间是多少?
- 从外向内画圈时,内圈相比外圈起始位置 + 1,终止位置 - 1。
- 当起始位置等于终止位置时,边界条件的填充。
3. 代码展示
class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int count = 1, start = 0, end = n - 1;
while (start < end) {
for (int i = start; i <end; i++) {
matrix[start][i] = count++;
}
for (int i = start; i < end; i++) {
matrix[i][end] = count++;
}
for (int i = end; i > start; i--) {
matrix[end][i] = count++;
}
for (int i = end; i > start; i--) {
matrix[i][start] = count++;
}
start++;
end--;
}
if (start == end) {
matrix[start][start] = count;
}
return matrix;
}
}
四、总结
至此,数组的大致方法就过了一遍。
回望去,大抵是通过双指针来操作:头尾指针、快慢指针、滑动窗口。这些巧妙的算法使我意识到,即使是最基础的数据结构也不容小觑。
深夜写博客竟然能够得到莫名的平静与安心。比起躺在床上会想要虚无地看手机,这样更令我觉得安心。
当然最好还是不要搞这么晚了,尽量早早休息。
祝我自己学习愉快~~~
文章介绍了使用双指针和滑动窗口法解决编程问题的实例,包括有序数组平方、长度最小子数组和螺旋矩阵II。通过这些技巧,展示了数组操作在IT技术中的应用和优化策略。

被折叠的 条评论
为什么被折叠?



