文档讲解:代码随想录
977 有序数组的平方
第一遍写的时候没有理解到非递减数组是什么意思
非递减数组是指数组中的元素从左到右不会递减(可以相等),也就是说,数组中的每个元素要么大于等于前一个元素,要么和前一个元素相等。这意味着数组中的元素可以按照从小到大的顺序排列,但在排序过程中允许相同元素出现在相邻位置。
自己写的暴力解法,最后未排序(排序算法也不会写),导致只有27个用例通过。
双指针法:
双指针法并非只有27题那么一种用法。27题我们使用的是一个指针选取数据,一个指针更新数据。
此题我们使用的是一个指向起始位置,一个指向结束位置。
class Solution {
public int[] sortedSquares(int[] nums) {
int k = nums.length-1;
//起始位置
int i = 0;
//结束位置
int j = nums.length-1;
int[] result = new int[nums.length];
while(i<=j){
if(nums[i] * nums[i] < nums[j] * nums[j]){
result[k--] = nums[j] * nums[j];
j--;
}else{
result[k--] = nums[i] * nums[i];
i++;
}
}
return result;
}
}
209 长度最小的子数组
注意:1.长度最小 2.连续子数组
这题题目暴力解法是两个for循环,然后不断的寻找符合条件的子序列,时间复杂度是O(n^2)。在力扣上是超时的。
滑动窗口
所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
视频链接:
用一个for循环来完成两个for循环所做的事情。
需要思考理解的是,循环中的i++的i到底指的是数组的起始位置还是终止位置。
- 如果i指的是起始位置的话,终止位置依旧需要遍历一边,其实和暴力解法的思路是一样的
- 如果i指的是终止位置,起始位置使用动态移动的策略就可以了,这样才能用一个for循环来解决,这也是滑动窗口的精华。
如何移动起始位置呢?
当发现集合中的元素和大于等于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;
}
}