解题思路
最简单的办法就是遍历求平方,最后再将结果进行排序,但是这明显不是出题者的想要考查的点,可以选择双指针解法,首先声明一个队列,从两端开始遍历数组,循环比较两个端点的平方的大小,依次将大的值如队列。
var sortedSquares = function(nums) {
const result = []
let left = 0,right = nums.length -1
while(left<=right){
if(nums[left]**2<=nums[right]**2){
result.unshift(nums[right]**2)
right --
} else {
result.unshift(nums[left]**2)
left++
}
}
return result
};
时间复杂度O(n)
209. 长度最小的子数组
题目描述
解题思路
同样,该题也可以使用暴力循环,使用两次循环,统计累加和大于目标值的字串最小长度。
可以使用滑动窗口,在一个循环中使用两个索引,一个表示字串开始位置,一个表示字串结束位置,先让字串结束位置随着循环右移,同时累加字串和,当大于目标值时开始移动字串起始位置,同时更新字串和,比较每个满足条件的字串长度,取最小值。
var minSubArrayLen = function(target, nums) {
// // 滑动窗口解法
let sum = 0; // 累加和
let len = nums.length+1; // 最小长度
let currentLen = 0 // 当前最小长度
let i = 0 ; // 滑动窗口起点
for(let j=0;j<nums.length;j++){ // j表示滑动窗口终点
sum += nums[j]
while(sum>=target){ // 累加和大于目标值 ,说明左边该移动了
currentLen = j - i + 1 // 当前子数组长度
len = currentLen < len ? currentLen:len
sum -= nums[i]
i++ // 起始右移
}
console.log(len)
}
return len > nums.length ? 0 :len
};
滑动窗口重点:
1.窗口内是什么?
2.如何移动窗口的起始位置?
3.如何移动窗口的结束位置?
59. 螺旋矩阵 II
解题思路
模拟顺时针画矩阵的过程:
填充上行从左到右
填充右列从上到下
填充下行从右到左
填充左列从下到上
需要注意的同二分法一样需要按照相同的开闭规则来循环,注意边界,特殊处理n为基数时的中间数据。
var generateMatrix = function(n) {
let startX = 0
let startY = 0 // 初始化X Y坐标值
let res = Array.from(Array(n), () => Array(n))
let loop = Math.floor(n / 2); // 循环层级 取整,奇数单独处理最中间的数据
let mid = Math.floor(n / 2)
let count = 1; // 初始化数组第一个数字为1
let offset = 1; // 初始化 循环始终维持左闭右开,第一轮循环右边界为n-1,每轮循环后边界依次减一
while (loop--) {
let i = startX
let j = startY
// 第一轮循环,从左到右
for (j = startY; j < n - offset; j++) {
res[i][j] = count++
}
// 从上到下
for (i = startX; i < n - offset; i++) {
res[i][j] = count++
}
// 从右到左
for (; j > startY; j--) {
res[i][j] = count++
}
// 从下到上
for (; i > startX; i--) {
res[i][j] = count++
}
// 每轮循环结束后 坐标依次加1 偏移量加1
startX++
startY++
offset++
}
if (n % 2 != 0) {
res[mid][mid] = n ** 2
}
return res
};