参考文章与视频
题目一:977.有序数组的平方
题目描述
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。977. 有序数组的平方 - 力扣(LeetCode)
示例 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]
要求:时间复杂度为 O(n)
第一想法
遍历数组计算每一项元素的平方,然后排序。排序时间复杂度要求O(n),这里没什么想法,想到的时间复杂度都超过了O(n)。
看完代码随想录之后的想法
需要注意的是,原数组其实也是有序的,但是因为负数平方后可能会大于所以造成了平方后的无序。但这种情况下负数部分平方后也是有序的,由大到小。这时,我们可以设定左右指针,分别从前向后,从后向前移动比较,并从后向前填入新数组中。
var sortedSquares = function(nums) {
let len = nums.length;
let arr = new Array(len).fill(0);
let left = 0;
let right = len - 1;
for(let i = len-1; i >=0 ; i--) {
if(nums[left]*nums[left] > nums[right]*nums[right] ) {
arr[i] = nums[left]*nums[left];
left++;
} else {
arr[i] = nums[right]*nums[right];
right--;
}
}
return arr;
};
题目二:209.长度最小的子数组
题目描述
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
第一想法
遍历数组 ,以当前数组元素为起始子数组找到满足和大与等于s的数组,并记录,如果找到长度更小的就更新记录直到最后。
var minSubArrayLen = function(target, nums) {
let result = nums.length;
let flag = false;
let len = 0;
for (let i = 0; i < nums.length; i++) {
let sum =0;
for (let j = i; j < nums.length; j++) {
sum = sum + nums[j];
if (sum >= target) {
len = j-i+1;
if(len < result){
result = len;
}
flag = true;
}
}
}
if (flag) {
return result;
} else {
return 0;
}
};
看完代码随想录之后的想法
利用双指针构建滑动窗口,不断调整指针以满足窗口所选中的子数组符合我们的目标结果。
构建滑动窗口需要明确:
窗口包含的元素之和应大与等于target;
当窗口包含子数组满足条件,窗口起始指针应向后移动;
窗口终止指针应持续滑动直至遍历完原数组。
var minSubArrayLen = function(target, nums) {
let result = nums.length+1;
let sum = 0;
let l = 0;
for (let r = 0; r < nums.length; r++) {
sum = sum + nums[r];
while(sum >=target) {
result = result > r-l+1 ? r-l+1 : result;
sum = sum - nums[l];
l++;
}
}
if(result == nums.length+1) return 0;
return result;
};
实现中遇到的困难
1.计算sum和符合条件的长度位置和方式很重要,长度可以直接通过j-i+1求。应先计算sum后判断是否满足target,满足则输出长度。
2.计算长度使用累加方法,增加了复杂度,每次都要重新赋值长度初值,但是这个初值很容易在最后被误当成最小值赋值给result。
3.在使用滑动窗口时,起始指针向右移动的同时也应让sum减去移出窗口的元素。
题目三:59.螺旋矩阵II
题目描述
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
第一想法
先创建一个n*n大小的数组,依次赋值。
看完代码随想录之后的想法
同样要遵循循环不变量原则,循环不变量是指控制边每次的计算区间一致,为了控制这个边每次具有相同的计算区间,我们每次填充数字应不包含该边最后一个点,应把最后一个节点交给下一条边处理。
var generateMatrix = function(n) {
let startX = startY = 0; // 起始位置
let loop = Math.floor(n/2); // 旋转圈数
let mid = Math.floor(n/2); // 中间位置
let offset = 1; // 控制每一层填充元素个数
let count = 1; // 更新填充数字
let res = new Array(n).fill(0).map(() => new Array(n).fill(0));
while (loop--) {
let row = startX, col = startY;
// 上行从左到右(左闭右开)
for (; col < startY + n - offset; col++) {
res[row][col] = count++;
}
// 右列从上到下(左闭右开)
for (; row < startX + n - offset; row++) {
res[row][col] = count++;
}
// 下行从右到左(左闭右开)
for (; col > startY; col--) {
res[row][col] = count++;
}
// 左列做下到上(左闭右开)
for (; row > startX; row--) {
res[row][col] = count++;
}
// 更新起始位置
startX++;
startY++;
// 更新offset
offset += 2;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2 === 1) {
res[mid][mid] = count;
}
return res;
};
实现中遇到的困难
如果n为奇数的话,需要单独给矩阵最中间的位置赋值