977. 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入: nums = [-7,-3,2,3,11]
输出: [4,9,9,49,121]
思路
双指针法:
因为数组是有序的,因此数组最后面的数字的平方一定是大于前面数的平方,但考虑到可能存在负数的原因,因此我们需要比较最左边和最右边的的数字平方的大小;
例如 (4)^2 > 3^2 但是 -4 < 3。
因此我们需要两个指针,一个指向最左边,一个指向最右边,每次比较左指针数的平方和右指针数的平方,哪个更大则放入新数组的最后面,同时移动指针。
注意: 新数组一定要从后往前,因为最大的平方一定是原数组最左或最右的数中的一个的平方,而最小的则不然。
class Solution {
public int[] sortedSquares(int[] nums) {
int pre = 0;
int post = nums.length - 1;
int[] res = new int[nums.length];
int idx = post;
while (pre <= post) {
int preNum = nums[pre] * nums[pre];
int postNum = nums[post] * nums[post];
if (postNum > preNum) {
res[idx--] = postNum;
post--;
} else {
res[idx--] = preNum;
pre++;
}
}
return res;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(n)
参考文章
209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
思路
快慢指针 + 滑动窗口:
快慢指针同时指向数组第一个值,快指针先以每次移动一位的速度不停的向右移动,直到快慢指针区间的数的和sum大于或等于目标值target;当 sum >= target 时,慢指针开始移动,每次右移一格,同时sum -= nums[slow++],直到和小于目标值 while (sum >= target),这个操作期间要检查区间长度是否小于已知的最短长度,如果是,则更新最小长度。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int res = Integer.MAX_VALUE;
int slow = 0;
int val = 0;
for (int fast = 0; fast < nums.length; ++fast) {
val += nums[fast];
while (val >= target) {
res = Math.min(res, fast - slow + 1);
val -= nums[slow++];
}
}
return res == Integer.MAX_VALUE ? 0 : res;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
参考文章
59. 螺旋矩阵 II
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
思路
思路很简单,就是简单的嵌套循环,然后需要注意的点非常多。
- 从左到右,从上到下,从右到左,从下到上分别用四个
for循环解决;循环的次数为n/2这点如果画了图就非常清晰(如图一)。 - 循环不变量:坚持左闭右开原则,这里表示为从第一个数,到每一行或者每一列的倒数第二个数为止,最后一个数留给下一个
for循环作为开始元素。如图二,每一种颜色代表一个for循环 - 判断
n的奇偶,如果为奇数的话矩阵最中间的那个数字是无法遍历到的,因此我们要手动赋值。
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0;
int start = 0;
int count = 1;
int i,j;
int[][] res = new int[n][n];
while (loop++ < n/2) {
for ( j = start; j < n - loop; ++j) {
res[start][j] = count++;
}
for ( i = start; i < n - loop; ++i) {
res[i][j] = count++;
}
for ( ; j >= loop; --j) {
res[i][j] = count++;
}
for ( ; i >= loop; --i) {
res[i][j] = count++;
}
start++;
}
if (n % 2 == 1) {
res[start][start] = count;
}
return res;
}
}
- 时间复杂度 O(n^2)
- 空间复杂度 O(1)
图1
图2