977 有序数组的平方
思路:这道题可以使用双指针,在数组的左右两边设有指针,比较指针指向的值的平方的大小,将最大值放在新的数组中,只是是从后往前方的(因为题目要求递增,如果从前面放,需要将新数组倒序,效率会低一些),然后相应的指针向中间靠拢
代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> res(nums.size(),0);//创建一个右nums.size()个元素的数组,每个初始为0
int number=nums.size()-1;//最后一个元素的下标
for(int left=0,right=nums.size()-1;left<=right;)//定义左右指针并确定循环条件
{
if(nums[left]*nums[left]>nums[right]*nums[right])//左边的大,放左边的,left指针右移
{
res[number--]=nums[left]*nums[left];
left++;
}else //左边的大或者等于的情况
{
res[number--]=nums[right]*nums[right];
right--;
}
}
return res;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
209 长度最小的子数组
暴力思路:用两个for循环,不断寻找合适的子序列,但会超时
代码:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int res=1e5+10;
bool isok=false;
for(int i=0;i<nums.size();i++)
{
int sum=0;
for(int j=i;j<nums.size();j++)
{
sum+=nums[j];
if(sum>=target)
{
res=min(res,j-i+1);
isok=true;
break;
}
}
}
if(!isok)res=0;
return res;
}
};
时间复杂度O(n^2)
空间复杂度O(1)
滑动窗口思路:暴力时找到了合适的子序列后是将起始点后移一位,那么那么新的子序列中会有与上一个子序列重复的(从新的起始位置到旧的终止位置),那么滑动窗口就是利用了这个重复的部分,保留从新的起始位置到旧的终止位置的这段结果,利用双指针来实现起始位置与终止位置的变化
代码:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left=0,sum=0;
int res=INT32_MAX;//c++标准库定义的宏,表示32位有符号整数能表示的最大值(大概就是int的最大值)
for(int right=0;right<nums.size();right++)//在
{
sum+=nums[right];
while(sum>=target)//这里不能用if,否则无法覆盖到所有的情况
{
int strength=right-left+1;
res=res>=strength?strength:res;
cout << sum << endl;
sum-=nums[left++];
}
}
return res<=nums.size()?res:0;
}
};
这是KIMI总结的为什么不用if
时间复杂度O(n)
空间复杂度O(1)
59 螺旋矩阵
思路:规律很清楚,就是转换为代码有点困难,实际上就需要四步
- 在最上:从最左到最右,最上面的完成了,将最上加一并判断是否大于最下
- 在最右:从最左到最下,最左面的完成了,将最右减一并判断是否小于最左
- 在最下:从最右到最左,最下面的完成了,将最下减一并判断是否小于最上
- 在最左:从最下到最上,最左面的完成了,将最左加一并判断是否大于最右
这样就正好完成了,最上最下最左最右在运行的过程中变化,将需要填上数字的矩阵缩小,判断是判断矩阵的合法性
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
int u=0;//最上
int d=n-1;//最下
int l=0;//最左
int r=n-1;//最右
int count=1;
vector<vector<int>> res(n,vector<int> (n,0));//这个需要注意一下,使用vector开辟二维数组
if(n==0)return res;
while(true)
{
for(int i=l;i<=r;i++) res[u][i]=count++;
if(++u>d)break;
for(int i=u;i<=d;i++) res[i][r]=count++;
if(--r<l)break;
for(int i=r;i>=l;i--)res[d][i]=count++;
if(--d<u)break;
for(int i=d;i>=u;i--)res[i][l]=count++;
if(++l>r)break;
}
return res;
}
};
时间复杂度o(n^2)
空间复杂度O(1)
力扣中的54和146都可以这么写
54:添加链接描述
146:添加链接描述
注意注意54,59的数据都保证了矩阵不会是空的,但是146没有,要加一个判断是否为空