977.有序数组的平方
977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
平方的特点是会把负数变成正数,所以一个负数和一个正数平方后的大小要根据绝对值来比较。
可以把元素 0 作为分界线,0 左侧的负数是一个有序数组 nums1,0 右侧的正数是另一个有序数组 nums2,那么这道题就和 88. 合并两个有序数组 讲过的 21. 合并两个有序链表 的变体。
所以,我们可以去寻找正负数的分界点,然后向左右扩展,执行合并有序数组的逻辑。不过还有个更好的办法,不用找正负分界点,而是直接将双指针分别初始化在 nums 的开头和结尾,相当于合并两个从大到小排序的数组,和 88 题类似。有了思路,直接看代码吧。
var sortedSquares = function(nums) {
//双指针
let i = 0;
let j = nums.length - 1;
let res = [];
while (i <= j) {
if (Math.abs(nums[i]) > Math.abs(nums[j])) {
res.unshift(nums[i] * nums[i]);
i++;
} else {
res.unshift(nums[j] * nums[j]);
j--;
}
}
return res;
}
var sortedSquares = function(nums) {
//先平方再排序
return nums.map(item=>item*item).sort((a,b)=>a-b)
}
209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
var minSubArrayLen = function(target, nums) {
//滑动窗口
//思路:定义一个滑动窗口,窗口内的和大于等于target时,记录窗口的长度,
//然后窗口左边界右移,直到窗口内的和小于target,窗口右边界右移,继续判断
let i = 0;
let j = 0;
let sum = 0;
let res = Infinity;
while (j < nums.length) { //j往后走
sum += nums[j];
while (sum >= target) { //i往后走
res = Math.min(res, j - i + 1);
sum -= nums[i];
i++;
}
j++;
}
return res === Infinity ? 0 : res;
};
59.螺旋矩阵II
59螺旋矩阵
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
解题的核心思路是按照右、下、左、上的顺序遍历数组,并使用四个变量圈定未遍历元素的边界,随着螺旋遍历,相应的边界会收缩,直到螺旋遍历完整个数组。
var generateMatrix = function(n) {
//思路:定义四个边界,然后按照顺时针的方向遍历
let left = 0;
let right = n - 1;
let top = 0;
let bottom = n - 1;
let res = [];
for (let i = 0; i < n; i++) {
res[i] = [];
}
let num = 1;
while (num <= n * n) { //循环条件
for (let i = left; i <= right; i++) { //从左到右
res[top][i] = num++;
}
top++;
for (let i = top; i <= bottom; i++) {//从上到下
res[i][right] = num++;
}
right--;
for (let i = right; i >= left; i--) {//从右到左
res[bottom][i] = num++;
}
bottom--;
for (let i = bottom; i >= top; i--) {//从下到上
res[i][left] = num++;
}
left++;
}
return res;
}