代码随想录算法训练营第二天| 977. 有序数组的平方,209. 长度最小数组 ,59.螺旋矩阵
977.有序数组的平方题目链接:leetcode 977 Squares of a Sorted Array
看到题目想考虑双指针,数组其实是有序的, 只不过负数平方之后可能成为最大数了。
class Solution {
public int[] sortedSquares(int[] nums) {
int l = 0 , r = nums.length-1; //起始位置指针和终止位置
int[] res = new int[nums.length]; //保存答案
int j = nums.length - 1; //从终止位置保存
while(l<=r){ //利用二分
if(nums[l]*nums[l]>nums[r]*nums[r]){
res[j--]=nums[l]*nums[l]; //对比两头的值,保存在res[j]
l++;
}else{
res[j--]=nums[r]*nums[r];
r--;
}
}
return res;
}
}
这道题不是快慢指针的形式,而是头尾指针向中间夹逼,
所以循环条件与之前不同。
209 长度最小数组 leetcode 209 Minimum Size Subarray Sum
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int start = 0,end = 0; //快慢指针
int sum = 0,min=Integer.MAX_VALUE; //设置一个最大值
while(end < nums.length){ //遍历快指针
sum +=nums[end++]; //把每一个数组的值累加到sum
while(sum>=target){ //
min = Math.min(min,end - start); //比较最大值和快指针和满指针位置差
sum -= nums[start]; //再减去最前面的值
start++; //满指针移动
}
}
return min == Integer.MAX_VALUE ? 0:min; //比较
}
}
滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
实现滑窗功能需要想三点:
- 窗口内是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
题目中:
- 窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
- 窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
- 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
其中为什么是while(sum >= target)因为容易存在target=101,nums=[1,1,1,1,100]的数组问题,
如果是if则无法解决此问题,所以用while
- 时间复杂度:O(n)
- 空间复杂度:O(1)
59 螺旋矩阵II leetcode 59 Spiral Matrix II
-
class Solution { public int[][] generateMatrix(int n) { int l = 0 , r = n-1 , t = 0 , b = n -1; int res[][] = new int[n][n]; int sum = 1; //设置开始值 while(sum<=n*n){ for( int i = l;i <= r;i++){//从左到右 res[t][i] = sum++; //t是头层 } t++; for(int i = t; i<=b;i++){//从上到下 res[i][r] = sum++; //r是右层 } r--; for(int i = r;i>=l;i--){//从右到左 res[b][i]= sum++; //b是底层 } b--; for(int i = b;i >= t; i--){//从下到上 res[i][l] = sum++; //l是左层 } l++; } return res; } }
坚持循环不变量原则,每条边都坚持左闭右开,这样一圈下来才能按照统一规则画下来
今天是三种题型
-
1是双指针的夹逼
-
2是滑动窗口
-
3是模拟行为
-
数组主要还是双指针算法,考虑边界问题还有条件的问题,