双指针法,数组有序且没限制数组元素的大小,因此数组元素平方后最大元素一定在数组两侧。要求目标数组按照递增顺序排序,因此比较原数组最外侧的两个元素的大小,将计算后大的值倒序填充到目标数组同时下标向数组中间靠拢。注意边界条件left <= right!
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length - 1;
int[] result = new int[nums.length];
int index = right;
while (left <= right) {
if (nums[left] * nums[left] > nums[right] * nums[right]) {
result[index--] = nums[left] * nums[left];
left++;
}else if (nums[left] * nums[left] < nums[right] * nums[right]) {
result[index--] = nums[right] * nums[right];
right--;
}
}
return result;
}
采用滑动窗口的思想,即不断的调节子区间的起始位置和结束位置,从而找到目标结果。
滑动窗口用一次for遍历,遍历的索引是滑动窗口的结束位置!
窗口内代表的是满足条件的数组,当窗口内的值大于目标值需要减小窗口长度,起始位置向右移动;当窗口内的值小于目标值,需要增大窗口长度,结束位置向右移动。
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;
}
}
判断边界,上侧从左向右遍历的边界是什么?右侧从下向上遍历的边界是什么?下侧?左侧?理解什么是循环不变量。
ublic int[][] generateMatrix(int n) {
int loop = 0; // 控制循环次数
int[][] result = new int[n][n]; // 目标数组
int start = 0; // 每次循环的开始点
int count = 1; // 每次填充的次数
int i, j;
while (loop++ < n / 2) { // 判断边界,上下左右的边界
// 模拟上侧从左到右
for(j = start; j < n - loop; j++) {
result[start][j] = count++;
}
// 模拟右侧从上到下
for (i = start; i < n - loop; i++) {
result[i][j] = count++;
}
// 模拟下侧从右到左
for (; j >= loop; j--) {
result[i][j] = count++;
}
// 模拟左侧从下到上
for (; i >= loop; i--) {
result[i][j] = count++;
}
start++;
}
// 最后一个位置,n为奇数时最中间的位置
if (n % 2 == 1) {
result[start][start] = count;
}
return result;
}