提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:以下是本篇文章正文内容,下面案例可供参考
977.有序数组的平方(碰撞指针)
1.思路
- 定义两个指针分别指向原数组的首尾部分,定义一个新数组接收数据
- 两个指针指向的数据平方后大小比较,值较大的指针将它的数值赋给新数组,并且移动到下一项
- 两个指针相向而行,直到相遇
2.题解
class Solution {
public int[] sortedSquares(int[] nums) {
int right = nums.length - 1;
int left = 0;
int[] result = new int[nums.length];
int index = result.length - 1;
while (left <= right) {
if (nums[left] * nums[left] > nums[right] * nums[right]) {
// 正数的相对位置是不变的, 需要调整的是负数平方后的相对位置
result[index--] = nums[left] * nums[left];
++left;
} else {
result[index--] = nums[right] * nums[right];
--right;
}
}
return result;
}
}
209.长度最小的子数组(滑动窗口)
1.思路
- 定义左右两个指针构造一个滑动窗口,开始时都指向数组首元素,定义一个新的元素result来接收结果
- 右指针不断右移,在这个过程中以左右指针为起始和结尾的所有元素不断求和,当和大于目标元素时右指针停止移动,将此时的左右指针间元素个数赋给result
- 左指针开始向右移动,每次都比较窗口元素和是否大于目标元素,若大于,就将此时左右指针间元素个数和result比较,把较小值新赋给result
- 当这个窗口中元素的值不满足和大于目标元素时左指针停止移动
- 右指针重新移动,重复进行前面三步,直到右指针走到数组最后,左指针也无法移动
2.题解
class Solution {
// 滑动窗口
public int minSubArrayLen(int s, int[] nums) {
int left = 0;
int sum = 0;
//result初始值赋值最大值,保证能将滑动窗口第一次满足条件时的值赋给result
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;
}
}
注意result初始值的设置
59.螺旋矩阵II
1.思路
- 首先确定要转的圈数为n/2,并且奇数数情况要考虑正方形矩阵最中间元素为nums[n/2][n/2]
- 定义填充数字count,不断自增填入数组
- 定义横向、纵向起始值每次开始新循环都加1,定义offset = 1需要控制每一条边遍历的长度,每次循环offset+1,右边界收缩一位
- 判断边界后,开始用count给数组元素赋值,分别考虑四种情况:上侧从左到右,右侧从上到下,下侧从右到左,左侧从下到上(全程保持左闭右开,不给最后一个元素赋值)
- 循环n/2次,把正方形矩阵填充,若存在阵最中间元素再单独赋一次值
2.题解
class Solution {
public int[][] generateMatrix(int n) {
int startx=0;
int starty=0;
int loop = n/2; // 控制循环次数
int mid = n/2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int[][] res = new int[n][n];
int count = 1; // 定义填充数字
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i, j;
while (loop-->0) { // 判断边界后,count从1开始
// 模拟上侧从左到右
for (j = starty; j < n - offset; j++) {
res[startx][j] = count++;
}
// 模拟右侧从上到下
for (i = startx; i < n - offset; i++) {
res[i][j] = count++;
}
// 模拟下侧从右到左
for (; j > starty; j--) {
res[i][j] = count++;
}
// 模拟左侧从下到上
for (; i > startx; i--) {
res[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if (n % 2 == 1) {
res[mid][mid] = count;
}
return res;
}
}
总结
- 今天学习了把怎样把双指针使用的更灵活
- 螺旋矩阵题目思路容易理解,但是循环要设置的限制条件很多,感觉掌握不太熟练