977.有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
var sortedSquares = function(nums) {
let newArray=new Array(nums.length).fill(0) //定义新数组
let k = nums.length-1 //定义索引下标
//定义两个下标
let i=0
let j=nums.length-1
while(i<=j){
if(nums[i]*nums[i]>nums[j]*nums[j]){
newArray[k]=nums[i]*nums[i]
k--
i++
}else{
newArray[k--]=nums[j]*nums[j]
j--
}
}
return newArray
};
第一想法:
我先想到的是快速排序,直接遍历数组,然后设定一个新数组为每一项的平方,再进行排序。双指针法,我想了一会儿不是很能理解,就去看了题解,题解某一些地方也不是很理解,我果断就去看卡哥的视频,不得不说,真的讲的很清楚。疯狂表白卡哥!
看完视频之后收获:
1.首先定义一个新数组
2.定义数组的索引下标
3.定义两个下标,i和j—i为最左边的值所对应的下标,j为最右边的值所对应的下标。由于数组中有负数,且是从小到大依次递增,所以每一项平方之后最大的值要么在最左边,要么在最右边,即从两边向中间依次递减。那么就采用双指针,从两边到中间逐步就得到了由大到小的数组。
附上图片:
4.判断最左边的值的平方和最右边的值的平方,若最左边的平方大于最右边的平方,那么将左边的平方赋值给新数组最后的下标所对应的数组空间,并且将i向右边移动一位,返之同理。
5.返回新数组即可
反思:
我理解之后去写代码,我写出来运行没有报错,但发现和预期结果是不同的,我去检查发现了一个愚蠢甚至是手误的错误,定义最右边下标j的时候定义成了数组的长度,没有减一,还是那句话,代码错误中有很多是手误,一定要留心手下。
209.长度最小的子数组
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
var minSubArrayLen = function(target, nums) {
let i = 0 //i表示起始位置
//j表示的是终止位置
let sum=0
let result=Infinity //定义为无穷大时才能不断的去更新取最小值
for(let j = 0;j<nums.length;j++){
sum+=nums[j]
while(sum>=target){
newArrayL=j-i+1 //得到的新数组的长度
result=Math.min(result,newArrayL) //result为最终取的最小的长度
sum-=nums[i] //移动起始位置
i++
}
}
return result
};
第一想法:
说实话我第一想法就纯粹暴力解法,两个for循环,一个加一个与所给定的值相比较,但是这个过于麻烦,我就去看了卡哥的视频,卡哥提到了滑动窗口的思想,即用一个for循环解决两个for循环的事情。
附上卡哥的视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
看完视频之后的收获:
1.首先定义一个起始位置和终止位置,for循环控制终止位置,动态的调整起始位置,这样就可以在终止位置从0开始遍历的时候,伴随着起始位置动态的调整来收集不同区间的和。
2.定义sum,来记录数组中元素相加的和
3.只要sum大于等于target的时候,返回所得到这个数组区间的长度
4.定义一个result首先为无穷大,这样可以保证不断地去更新取到最小值。最小长度就在无穷大和所得到的新数组长度中取最小的值。
5.移动起始值,sum则为刚开始收集的终止位置所得到的总和减去起始位置的数。向右移动
6.最后返回result即可
反思:
我看完视频去写的时候写完之后一直报错,才发现我没有定义result的值为无穷大,这样没有办法持续的去更新,所以会报错,我还开始在想为什么要让result的值为无穷大,只有无穷大时,才能找到最小的。
总结:
我刷的有点慢,明天周末准备把进度跟上,但我有每天都在刷,只要不断往前走,一点点进步,总比不去思考,不去行动强的多。
59.螺旋矩阵II
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
var generateMatrix = function(n) {
let startx=0; //起点
let starty=0; //终点
let count=1; //计数器
let offset=1; //控制终止位置
let loop=Math.floor(n/2) //旋转的圈数
let nums=new Array(n).fill(0).map(()=>new Array(n).fill(0)) //定义一个新数组
// 当n为偶数时
while(loop--){
let i=startx,j=starty
for(;j<n-offset;j++){
nums[startx][j]=count++
}
for(;i<n-offset;i++){
nums[i][j]=count++
}
for(;j>starty;j--){
nums[i][j]=count++
}
for(;i>startx;i--){
nums[i][j]=count++
}
startx++
starty++
offset++
}
// 当n为奇数时
if(n%2==1){
nums[startx][starty]=count
}
return nums
};
第一想法:
说实话我看到这个题目首先是不知道如何下手去解答的,我只想到了去循环每一条边,剩下的就不知道了,我直接去看了卡哥的视频。
在此继续附上卡哥的视频:https://www.bilibili.com/video/BV1SL4y1N7mV/
看完视频之后的收获:
1.卡哥把整体思路都讲解了一遍,矩形的四个角也就是所谓的边界点很重要。每一条边都要遵循循环不变量原则,这个不变量就是处理的规则统一,上面代码的每一条边的区间范围我都遵循的是左闭右开区间。
2.我们需要定义一下矩阵旋转的圈数和计数器:
假设是一个5x5的矩阵,如下图所示:
它需要转2圈,留下中间一个,所以矩阵旋转的圈数为所给定的正整数除以2
3.分为两种情况:第一种是如果给的正整数n为偶数
第二种情况是如果给的正整数n为奇数
4.先来看第一种情况下,定义startx和starty,在我理解来看这两个数就是表示的矩阵的每一项。我们再定义一个控制终止位置的变量。
然后我们开始进入循环,切记每一条边的起始位置都不固定,循环四条边。如上代码所示。第一圈循环完成之后,使startx,starty,offset都加一,直至循环至最中间即可。
5.再来看第二种情况下,如果无法被2整除,那么就直接将计数器的数赋值给startx和starty即可。
最后:
先自己思考如果思考太久没有任何思路,就去卡 视频,视频看完再写代码,我习惯性在看视频的时候边看边记录一些重要点,看完之后写的时候思考刚才视频中的点,看是否真正理解,能写出来,写个大概之后再运行代码出错再不断地修改,这是一个循序渐进的过程,加油啊!