977.有序数组的平方
题目链接: 977.有序数组的平方
参考文档:代码随想录
状态:已完成
耗时:一小时
思路:题目要求时间复杂度为O(n),开始花了二十分钟没有太多思路,仅想到输入数组仍是有规律可循,可以分开正数负数两部分处理。后续发现了主要突破点:题目没有要求空间复杂度,且明确要求返回数组,而不是直接用nums,因此想到了新建数组,并使用双指针的写法:
解法一:
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortedSquares = function(nums) {
let count = 0;
let result = [];
for(let i = 0; i< nums.length; i++){
if(nums[i]<0){
count++;
}
nums[i]=Math.pow(nums[i],2);
}
let j = count-1; //j是nums中最大负数的起始节点
let k = count; //k是nums中最小正数的起始节点
for(let i = 0; i< nums.length; i++){
if((nums[j]<=nums[k] && nums[j]!= null) || nums[k]==null){ //将已经平方的更小数字放入新数组中,如果nums正数部分已经遍历完毕,则将剩下的负数部分放入新数组,else if判断同理
result[i]=nums[j];
j--;
}
else if((nums[j]>nums[k] && nums[k]!= null) || nums[j]==null){
result[i]=nums[k];
k++;
}
}
return result;
};
解法二:考虑到将来工作需要,也可以直接使用sort()方法解决:
var sortedSquares = function(nums) {
for(let i = 0; i< nums.length; i++){
nums[i]=Math.pow(nums[i],2);
}
nums.sort((a, b) => a - b);
return nums;
};
这里有个坑,如果nums.sort()不带参数会按字符串大小来比较,得出来的结果未必是我们想要的,因此要写成sort((a, b) => a - b),这样就是按数字升序排序。
解法三:最后贴出代码随想录的参考答案,其实和解法一的思路是一样的,不过人家是从后往前地将元素插入新数组,这样在设置判断条件时会没这么复杂,大家也可以参考下:
var sortedSquares = function(nums) {
let n = nums.length;
let res = new Array(n).fill(0);
let i = 0, j = n - 1, k = n - 1;
while (i <= j) {
let left = nums[i] * nums[i],
right = nums[j] * nums[j];
if (left < right) {
res[k--] = right;
j--;
} else {
res[k--] = left;
i++;
}
}
return res;
};
解法三的代码确实更简洁些
977.有序数组的平方
题目链接: 977.有序数组的平方
参考文档:代码随想录
状态:已完成
耗时:半小时?
思路:第一版是从前往后遍历,算出第一段大于等于target后,统计元素个数,再跳过这段继续往下面遍历,参考答案后发现该解法是错的(但是leetcode测试用例太少了,我还是通过了),因为会遗漏一部分的解,代码如下:
var minSubArrayLen = function(target, nums) {
let count = 0;
let min = nums.length+1;
let sum = 0;
for(let i=0; i<nums.length;i++){
sum+=nums[i];
count++;
if(sum>=target && min>count){
min=count;
count=0;
sum=0;
}
}
return min==nums.length+1?0:min;
};
解法一:暴力算法,时间复杂度O(n):
var minSubArrayLen = function(target, nums) {
let count = 0;
let min = nums.length+1;
let sum = 0;
for(let i=0; i<nums.length;i++){
count=0;
sum=0;
for(let j=i;j<nums.length;j++){
sum+=nums[j];
count++;
if(sum>=target && min>count){
min=count;
count=0;
sum=0;
break;
}
}
}
return min==nums.length+1?0:min;
};
解法二:利用滑动区间解决问题,时间复杂度O(n):
var minSubArrayLen = function(target, nums) {
let min = nums.length+1;
let sum = 0;
let j = 0;
for(let i=0; i<nums.length;i++){ //i是快指针
sum += nums[i];
while(sum>=target){
min = Math.min(min,i-j+1);
sum = sum - nums[j];
j++;
}
}
return min == nums.length+1?0:min;
};
59.螺旋矩阵II
题目链接:59.螺旋矩阵II
参考文档:代码随想录
状态:已完成
耗时:两个小时
思路:能想到是对二维矩阵的四条边做处理,并且每条边只处理n-1个元素(这样处理每条边的时候就方便些),但是实际操作起来还是缝缝补补,靠debug补出了代码,并不可取:
代码:
var generateMatrix = function(n) {
let matrix = new Array(n).fill(0).map(() => new Array(n).fill(0));
let begin = 1;
for(let i = 0;i<n/2;i++){
if(i==Math.floor(n/2)){
matrix[i][i]=n*n;
break;
}
for(let j = i;j<n-1-i;j++){
matrix[i][j]= begin+j;
matrix[j][n-1-i]= begin+(n-1-i*2)+j;
matrix[n-1-i][j+1] = begin+(n-1-i*2)*3-j;
matrix[j+1][i] = begin+(n-1-i*2)*4-j;
console.log("");
}
begin = matrix[i+1][i];
}
return matrix;
};
代码随想录的解法:
function generateMatrix(n: number): number[][] {
let loopNum: number = Math.floor(n / 2);
const resArr: number[][] = new Array(n).fill(1).map(i => new Array(n));
let chunkNum: number = n - 1;
let startX: number = 0;
let startY: number = 0;
let value: number = 1;
let x: number, y: number;
while (loopNum--) {
x = startX;
y = startY;
while (x < startX + chunkNum) {
resArr[y][x] = value;
x++;
value++;
}
while (y < startY + chunkNum) {
resArr[y][x] = value;
y++;
value++;
}
while (x > startX) {
resArr[y][x] = value;
x--;
value++;
}
while (y > startY) {
resArr[y][x] = value;
y--;
value++;
}
startX++;
startY++;
chunkNum -= 2;
}
if (n % 2 === 1) {
resArr[startX][startY] = value;
}
return resArr;
};
总结:
- 可以使用ai造多些测试边界的用例
- 缝缝补补出来的代码不能算真正完成,还是要看他人的写法,明白怎样写更合理,掌握二刷也能顺利写出的写法才算完成。有思路但因写法不对导致耗时过长应有取舍地看答案。