LeetCode 977:
题目链接:有序数组的平方
第二次看到这个题目的思路依然是先平方后排序
双指针的思路:
-
看到题目提示双指针以后的思路是:找到第一个大于0的数,再他的左右各设置left和right指针,一个向左边延申,一个向右边延申- 每步填入result数组都是左右比较选小的
- 这种正向的方法写起来费劲,第一:还需要判断第一个大于0的数字与前一个数的绝对值究竟哪一个更小;第二:无法确定到底是那一边先到边界,还要再加入代码判断
- 逆向思维:结果数组从后往前填充!最大值一定都是在两边的,left和right指针向中间靠就行
public int[] sortedSquares(int[] nums){ int[] result = new int[nums.length]; int left = 0; int right = nums.length-1; int count=nums.length-1; while(count>=0){ int left2 = nums[left]*nums[left]; int right2 = nums[right]*nums[right]; if(left2>right2){ result[count--] = left2; left++; }else{ result[count--] = right2; right--; } } return result; }
LeetCode 209:
题目链接:长度最小的子数组
状态:还是只能想到暴力的解决办法
滑动窗口就是不断移动起始位置,结束位置,夹逼得到结果:
- 窗口内是什么
- 怎么移动窗口的起始位置
- 怎么移动窗口的结束位置
之前的误区:滑动窗口是固定窗口大小后移动
滑动窗口方法:
- 窗口内是要求和的值
- 当移动到 当前窗口的总和
>=target
就可以得到结束位置 - 在这种情况下,移动当前窗口的起始位置,直到当前窗口的总和
<target
public int minSubArrayLen(int target, int[] nums) {
int min = Integer.MAX_VALUE;
int sum = 0;
int left = 0;
for(int i=0;i<nums.length;i++){
sum+=nums[i];
//当移动到 当前窗口的总和 `>=target` 就可以得到结束位置
while(sum>=target){
min = Math.min(min, i - left + 1);
//移动当前窗口的起始位置,直到当前窗口的总和`<target`
sum-=nums[left++];
}
}
return min==Integer.MAX_VALUE?0:min;
}
LeetCode 59:
题目连接:螺旋数组II
模拟题,主要就是坚持左闭右开的思路,对于这种题目,我的做法就是先把循环体内的内容写出来,再考虑循环条件
public int[][] generateMatrix(int n) {
int[][] result = new int[n][n];
int count = 1;
int k=0;
while(k<=(n-1)/2){
for(int j=k;j<n-1-k;j++){
result[k][j] = count;
count++;
}
for(int i=k;i<n-1-k;i++){
result[i][n-1-k] = count;
count++;
}
for(int j=n-1-k;j>k;j--){
result[n-1-k][j] = count;
count++;
}
for(int i=n-1-k;i>k;i--){
result[i][k] = count;
count++;
}
k++;
}
if(n%2==1){
result[n/2][n/2] = count;
}
return result;
}