1. 977 有序数组的平方
题解: 采用双指针解法,由于数组中存在负数,因此平方之后数字的顺序可能会有变化,负数的平方还有可能大于负数,因此可以采用双指针从两头向中间遍历,然后采用结果数组,存储每次比较的值,代码如下
public int[] sortedSquares(int[] nums) {
// 双指针 指针从两头向中间遍历
int i = 0;
int j = nums.length - 1;
int k = nums.length;
int[] res = new int[k];
while (i <= j) {
if (nums[i] * nums[i] > nums[j] * nums[j]) {
res[--k] = nums[i] * nums[i];
i++;
}else {
res[--k] = nums[j] * nums[j];
j--;
}
}
return res;
}
}
2. 209 长度最小的子数组
题解: 长度最小的子数组,那么肯定是这一整个数组n的一部分,因此可以采用滑动窗口法来求解,从i开始,到j结束,i和j之间的总和大于等于target就是一个子数组,记录下来,然后把i向前移动,继续滑动窗口,特别秒的算法,具体代码如下:
public int minSubArrayLen(int target, int[] nums) {
// 双指针 i表示滑动窗口起始位置 j表示滑动窗口终止位置
int n = nums.length;
int sum = 0;
int res = Integer.MAX_VALUE; // 用来记录最后的长度;
int i = 0;
for (int j = 0; j < n; j++ ) {
sum += nums[j];
while (sum >= target) {
int subL = j - i + 1; //记录当时长度
res = Math.min(res, subL);
sum -= nums[i++];
}
}
return res == Integer.MAX_VALUE ? 0: res;
}
}
3. 59 螺旋矩阵II
题解: 非常经典的一个思路 左闭右开, 循环一圈 就相当于左闭右开区间 从左到右 从上到下 从右到左 从下到上的经历了左闭右开区间的一个循环,依次类推,代码实现如下:
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
// 左闭右开的思路
int loop = n >> 1; //表示循环的次数
int offset = 1; // 控制每条边遍历的长度
int startX = 0; // 每圈循环开始的位置
int startY = 0; // 结束的位置
int count = 1; //记录数
int i,j;
while (loop > 0) {
i = startX;
j = startY;
// 从左到右 左闭右开
for (j = startY; j < n + startY - offset; j++) {
res[startX][j] = count++;
}
// 从上到下 左闭右开
for(i = startX; i < n+startX -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 += 2;
loop--;
}
// 如果为奇数 需要单独给中间值进行赋值
if (n % 2 ==1) {
int mid = n >> 1;
res[mid][mid] = n * n;
}
return res;
}
}