977 有序数组的平方
最简单的可以想到的方法是把所有的的数都平方后直接sort,但是这样的时间复杂度是O(nlogn)。而我们想要一个更加有效率的办法。通过观察数组,我们可以发现最左边和最右边的元素的平方总是比中间的小。所以我们可以考虑使用双指针从左右两边向中间填数。
const n = nums.length
const res = new Array(n).fill(-1)
let left = 0, right = n - 1, write = n - 1
// 因为right最开始是n-1,所以终止条件是left>right
while (left <= right) {
if (nums[left] * nums[left] >= nums[right] * nums[right]) {
res[write] = nums[left] * nums[left]
left += 1
} else {
res[write] = nums[right] * nums[right]
right -= 1
}
write -= 1
}
return res
209 长度最小子数组
我们可以用滑动窗口来解决这道题,在滑动的同时维护左右指针之间的和,如果和小于target,右指针不断向右移并且curr变大。而当curr大于等于target时,我们向右移左指针来使可能的结果最短。
var minSubArrayLen = function(target, nums) {
let left = 0, right = 0
let res = Infinity, curr = 0
while (right < nums.length) {
const n = nums[right]
right += 1
curr += n
while (curr >= target) {
res = Math.min(right - left, res)
const d = nums[left]
left += 1
curr -= d
}
}
return res === Infinity ? 0 : res
};
59 螺旋矩阵2
这道题主要考查的是模拟数组,我们可以模拟四个边界然后依此填入数字。
var generateMatrix = function(n) {
const matrix = new Array(n).fill(0).map(() => new Array(n).fill(0))
let top = 0, bottom = n - 1, left = 0, right = n - 1
let num = 1
while (num <= n * n) {
if (top <= bottom) {
for (let i = left; i <= right; i++) {
matrix[top][i] = num
num += 1
}
}
top += 1
if (left <= right) {
for (let i = top; i <= bottom; i++) {
matrix[i][right] = num
num += 1
}
}
right -= 1
if (top <= bottom) {
for (let i = right; i >= left; i--) {
matrix[bottom][i] = num
num += 1
}
}
bottom -= 1
if (left <= right) {
for (let i = bottom; i >= top; i--) {
matrix[i][left] = num
num += 1
}
}
left += 1
}
return matrix
};