文档讲解:代码随想录
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
思路:
题目给出的数组保证有序,也就是说在数轴上是一个个点。同时我们知道,在数轴上越靠近0的点绝对值越小,其平方值也就越小。
我们首先遍历一遍该有序数组,很容易就能找到绝对值最小的那个点。从这个点为起点,不论向左还是向右,其平方值都是非递减顺序的一个数组。此时我们的题目变为两个非递减数组的合并问题。
两个有序数组的合并很好解决,双指针读取两个数组的值进行比较,存到第三个数组中即可。
核心代码:
class Solution {
private:
int abs(int x){
return x>0?x:-x;
}
public:
vector<int> sortedSquares(vector<int>& nums) {
int pos=0;
int len=nums.size();
vector<int> ans(len);
for(int i=0;iif(abs(nums[i])<abs(nums[pos])) pos=i;
}
int l,r;
if(nums[pos]<=0) l=pos,r=pos+1;
else l=pos-1,r=pos;
int cnt=0;
while(l>=0){
if(r==len||(nums[l]*nums[l])<=(nums[r]*nums[r])){
ans[cnt++]=nums[l]*nums[l];
l--;
}
else{
if(rwhile(rreturn ans;
}
};
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
思路:
本题要求找出长度最短的连续子数组,使其和大于等于目标值。
我们一样可以采取双指针解决这个问题,取双指针left和right,分别表示连续子数组的左端点和右端点,其初始值均为0。
针对当前子数组,我们统计其和sum。如果sum小于目标值target,说明还需要接着向里面读入,则right需要加1。如果sum大于等于目标值target,证明当前达到要求,可以进行滑动。
重复以上操作,我们相当于枚举每个点为子数组左端点,同时迅速的找出了符合要求的右端点。统计所有符合要求的数组长度,取最小值即可。
本题目是经典的滑动窗口问题。在统计sum的时候,我们可以在指针移动时对sum进行加减,也可以利用前缀和。
核心代码:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int l,r,ansl,ansr,sum;
int len=nums.size();
l=0;r=0;sum=0;
ansl=0;ansr=100005;
while(rwhile(l<=r&&sum>=target){
if(ansr-ansl>r-l){
ansl=l;
ansr=r;
}
sum-=nums[l];
l++;
}
sum+=nums[r];
r++;
}
while(l=target){
if(ansr-ansl>r-l){
ansl=l;
ansr=r;
}
sum-=nums[l];
l++;
}
if(ansr-ansl>len) return 0;
else return (ansr-ansl);
}
};
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
思路:
本题目要求将元素按顺序螺旋式填到矩阵中。
首先手推一下过程可以知道以下信息:螺旋式的方向是有规律的,按照“右下左上”重复进行,在碰到边界之前方向都不会变。这个所谓的“右下左上”其实就是“横向右移、竖向下移、横向左移、竖向上移”。针对这四个每个过程,我们都很容易进行实现,无非就是给x坐标或者y坐标加1或减1。
那么我们如何知道在什么时候碰到临界,或者说什么时候切换方向呢?
首先很明显的一点是,这个n*n的矩阵,所有横纵坐标必须位于[0,n-1]之间,不能超过这个边界。其次,我们很容易知道整个填充过程其实是由外到内的,所以我们填充到当前格子时,如果下一个格子已经被填充,那我们就知道也碰到临界了,需要切换方向,下一个方向按照“右下左上”来即可。问题就此得到解决。
另外,针对方向的处理我们其实是有小技巧的。我们可以提前写好位置向量数组dx和dy。其中dx[]={0,1,0,-1},dy[]={1,0,-1,0}。假设当前坐标为(x,y),易知(x+dx[0],y+dy[0])表示横向的下一个点,其他三个与此同理。同时我们用cnt记录方向,则0为右,1为下,2为左,3为上。需要切换方向时给cnt加1再对4取模即可。
核心代码:
class Solution {
public:
vector> generateMatrix(int n) {
std::vector row(n, -1);
std::vector> ans(n, row);
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int x=0,y=0,cnt=0;
for(int i=1;i<=n*n;i++){
ans[x][y]=i;
if(x+dx[cnt]<0||x+dx[cnt]>=n||y+dy[cnt]<0||y+dy[cnt]>=n
||ans[x+dx[cnt]][y+dy[cnt]]!=-1){
cnt++;
cnt%=4;
}
x=x+dx[cnt];
y=y+dy[cnt];
}
return ans;
}
};
今日学习时长4h,做题手感变好了很多,思路也清晰了不少。
同时学习了一些C++的八股文。