- Squares of a Sorted Array
Given an integer array
numssorted in non-decreasing order, return an array of the squares of each number sorted in non-decreasing order.
Example 1:
Input: nums = [-4,-1,0,3,10]
Output: [0,1,9,16,100]
Explanation: After squaring, the array becomes [16,1,0,9,100].
After sorting, it becomes [0,1,9,16,100].
Example 2:
Input: nums = [-7,-3,2,3,11]
Output: [4,9,9,49,121]
Constraints:
1 <= nums.length <= 104-104 <= nums[i] <= 104numsis sorted in non-decreasing order.
带负数的升序数组内元素平方后,最大值存在于数组的两端。因此使用两个指针指向头部和尾部。 这题很难做in-place的操作,因为如果要保证空间复杂度O(1)的话就需要在每次移动数组元素的时候,将其余所有元素向前移动一位。所以还是使用额外一个数组较好。
定义一个数组ans[nums.length], 与原数组等长。 循环检查头尾指针,将较大的元素从ans[]的尾部从后往前放。就可以得到结果。 要注意头尾指针循环的结束判断应该为while(left <= right), 不然会漏掉一个元素。
代码:
class Solution {
public int[] sortedSquares(int[] nums) {
int[] ans = new int[nums.length];
int k = nums.length - 1;
for(int i=0, j=nums.length - 1; i<=j;) {
int l2 = nums[i] * nums[i];
int r2 = nums[j] * nums[j];
if(l2 < r2) {
ans[k--] = r2;
j--;
}
else if (l2 >= r2) {
ans[k--] = l2;
i++;
}
}
return ans;
}
}
- Minimum Size Subarray Sum
Given an array of positive integers
numsand a positive integertarget, return the minimal length of a subarray whose sum is greater than or equal totarget. If there is no such subarray, return0instead.
Example 1:
Input: target = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: The subarray [4,3] has the minimal length under the problem constraint.
Example 2:
Input: target = 4, nums = [1,4,4]
Output: 1
Example 3:
Input: target = 11, nums = [1,1,1,1,1,1,1,1]
Output: 0
Constraints:
1 <= target <= 1091 <= nums.length <= 1051 <= nums[i] <= 104
这题使用滑动窗口,其实就是两个指针。 第一个指针为窗口起始index,为start, 另一个指针做循环数组, 为i。 [start, i] 为左右闭合区间,也就是这个滑动窗口。策略为:
- 若窗口内元素的SUM小于target, 挪动i,start不动。
- 若窗口内元素的SUM大于等于target, 挪动start,开始记录区间长度len,并在满足条件2的时候,更新len为更小值。这里需要循环挪动start,因为会存在{1,1,1,1,1,100...} target = 100 这样的情形。特别注意的是,挪动start时,SUM需减去start指向的元素。
- i移到数组末尾后,循环结束。 检查len值是否被更新过,因为len总是做最小值比较,初始化定义应为Integer.MAX_VALUE,最大整数值。如果len未被更新,返回0, 否则返回len
代码:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int len = Integer.MAX_VALUE;
int sum = 0;
int start = 0;
for(int i=0; i<nums.length; i++) {
sum += nums[i];
while(sum >= target) {
int current_len = i - start + 1;
len = Math.min(current_len, len);
sum -= nums[start++];
}
}
return len == Integer.MAX_VALUE ? 0 : len;
}
}
- Spiral Matrix II
Given a positive integer
n, generate ann x nmatrixfilled with elements from1ton2in spiral order.
Example 1:
Input: n = 3
Output: [[1,2,3],[8,9,4],[7,6,5]]
Example 2:
Input: n = 1
Output: [[1]]
Constraints:
1 <= n <= 20
这题似乎没什么取巧的方法,但思路清晰很重要。使用正确的策略可以保证思路清晰。 好的策略是,
- 以offset 来记录圈数,大循环每次写一圈数。
- 在每层大循环里,做四个小循环,写四条边。
- 在每个小循环中,只更新左闭右开的区间元素,留下最后一个元素给下一条边的任务,只在最后一条边,即处理左侧由下往上的边的时候,处理到最后。这样的好处是,每条边的逻辑处理是一致的。
- 注意,对n为奇数的情况,最中间的一个元素没有必要单独跑一圈,在大循环结束后,将最中间的元素直接赋值即可。
定义startx, starty为每一圈的起始坐标,每开始新的一圈前,startx++, starty++
代码为:
class Solution {
public int[][] generateMatrix(int n) {
int[][] ans = new int[n][n];
int startx = 0;
int starty = 0;
int offset = 1;
int i,j;
int count = 1;
while(offset <= n/2) {
for(j=starty; j<n-offset; j++) {
ans[startx][j] = count++;
}
for(i=startx; i<n-offset; i++) {
ans[i][j] = count++;
}
for(;j>offset-1;j--) {
ans[i][j] = count++;
}
for(;i>offset-1; i--) {
ans[i][j] = count++;
}
startx++;
starty++;
offset++;
}
//centre element when n is odd number
if(n%2 == 1) {
//odd
ans[n/2][n/2] = n * n;
}
return ans;
}
}