前言
今天的题目主要涉及到双指针,理解双指针的目的之后就不难,螺旋矩阵在大二考试时写过但没写出来,这次有了更好的理解。
Leetcode 977 有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/description/
代码随想录题解:代码随想录 (programmercarl.com)
思路:这个题的数组为有序数组且有负数,那么平方之后的最大值肯定在数组的两端,然后大小依次向中间递减。题目要求我们按递增顺序排列平方结果,那么我们结果数组就从尾部开始存即可。双指针在题目中起到的作用主要是遍历寻找当前数组最大值。
代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size(),0);
int k=nums.size()-1;
for(int i=0,j=nums.size()-1;i<=j;)
{
if(nums[i]*nums[i]>nums[j]*nums[j])
{
result[k]=nums[i]*nums[i];
k--;
i++;
}
else
{
result[k]=nums[j]*nums[j];
k--;
j--;
}
}
return result;
}
};
Leetcode 209 长度最小的子数组
思路:滑动窗口,用双指针模拟窗口滑动,一个左边界,一个右边界。先让右边界变大,如果发现和超过target,证明此时这个窗口里的子数组满足题意,先记录长度,然后缩小左边界并记录长度直到和小于target,此时应该增大有边界,最终结束条件为右边界抵达数组尾部。
代码:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i=0;
int j=0;
int result=INT32_MAX;
int sum=0;
int len=0;
for(j=0;j<nums.size();j++)
{
sum+=nums[j];
while(sum>=target)
{
len=j-i+1;
if(result>=len)
{
result=len;
}
else
{
result=result;
}
sum-=nums[i];
i++;
}
}
if (result==INT32_MAX)
{
return 0;
}
return result;
}
};
Leetcode 59 螺旋矩阵Ⅱ
思路:拿n=3举例,想清楚四个角什么时候填值,最好的想法是每个角就留给每次循环的第一个,即左上给第一次,遍历到右上不赋值右上,右上交给第二次,遍历到右下不赋值右下,右下交给第三次以此类推。还需要注意转几圈,这个模拟一下即可。最后注意hang,lie,offset边界每次转完一圈要++以及n为奇数时最中心特殊赋值。
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
int hang=0;int lie=0;int i,j;int offset=1;int count=1;int loop=n/2;
while(loop--)
{
for(j=lie;j<n-offset;j++) //注意结束条件
{
res[hang][j]=count;
count++;
}
for(i=hang;i<n-offset;i++) //注意结束条件
{
res[i][j]=count;
count++;
}
for(;j>lie;j--) //注意结束条件
{
res[i][j]=count;
count++;
}
for(;i>hang;i--) //注意结束条件
{
res[i][j]=count;
count++;
}
hang++; //记得++
lie++;
offset++;
}
if(n%2==1)
{
res[n/2][n/2]=count;
}
return res;
}
};
总结
我觉得算法既是一个理解的过程,也是一个记忆的过程,理解之后才能记得牢,记得牢证明已经理解,还是要多看多复盘。今天除此之外还学习了一点C++11的新特性,感觉对C++知识点的记忆体系还需要一段时间,时间还长继续加油。推荐一首最近很喜欢听的歌:种种可是(Anyway)