数组
题意:给你一个按非递减顺序排序的整数数组nums。返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
示例:
看到此题,我大致有两种思路:1.先将数组中元素平方,然后利用sort排序。2.利用双指针,准备工作:开辟一个大小等于nums的数组arr,两个指针一个指向数组开头,一个指向末尾,定义一个用于插入arr的指针;插入依据:左指针指向数组的平方大于右指针指向数组的平方,插入左元素,插入指针向前移动,右指针做法类似;循环终止:左指针大于右指针。
方法1代码:
vector<int> sortedSquares(vector<int>& nums) {
for(int i=0;i<nums.size();i++)
{
nums[i]=nums[i]*nums[i];
}
sort(nums.begin(),nums.end());
return nums;
}
方法2代码:
vector<int> sortedSquares(vector<int>& nums) {
//准备工作
vector<int> arr(nums.size());
int len=nums.size()-1;
int left=0,right=nums.size()-1;
while(left<=right)//终止条件
{
int leftNum=nums[left]*nums[left];//左指针元素的平方
int rightNum=nums[right]*nums[right];//右指针元素的平方
if(leftNum>rightNum)//插入条件
{
arr[len--]=leftNum;
left++;
}
else
{
arr[len--]=rightNum;
right--;
}
}
return arr;
}
题意:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和≥target的长度最小的 连续子数组,并返回其长度。如果不存在符合条件的子数组,返回0。
示例:
本题有两种思路:1.暴力求解,两次for循环,最外面循环就是起始位置,内层for循环表示从开头到该位置的和,若大于等于target,则记录len,然后跳出。2.双指针,利用双指针模拟滑动窗口,只需要一次for循环,遍历滑动窗口的右边界,让左边界和右边界开始都为0,然后让右边界不断移动,若发现有大于等于target的情况,记录len,然后对左边界不断缩小。
方法1代码:
int minSubArrayLen(int target, vector<int>& nums) {
int len=INT_MAX;
for(int i=0;i<nums.size();i++)
{
int Num=0;
for(int j=i;j<nums.size();j++)
{
Num+=nums[j];
if(Num>=target)
{
len=min(len,j-i+1);
break;
}
}
}
return len==INT_MAX?0:len;
}
方法2代码:
int minSubArrayLen(int target, vector<int>& nums) {
int sum=0;//窗口中元素的和
int len=INT_MAX;//窗口长度
int left=0;//窗口起始位置
for(int right=0;right<nums.size();right++)
{
sum+=nums[right];
while(sum>=target)//满足条件时,保存窗口长度
{
len=min(len,right-left+1);
sum-=nums[left];
left++;
}
}
return len==INT_MAX?0:len;
}
从上述思路我们不难看出,方法1的时间复杂度为O(n^2),是通过不了leetcode的;而方法2,我们使用双指针的思想,将两次遍历的事件缩短为了一次,时间复杂度降低了一倍,为0(n)。这里我们还需要理解时间复杂度的概念:这里时间复杂度判断标准是数组中元素的遍历次数,我们只遍历了一次,所有while并不会增加时间复杂度。
题意:给你一个正整数n,生成一个包含1到n2所有元素,且元素按顺时针顺序螺旋排列的n x n正方形矩阵matrix 。
示例:
本题并没有涉及算法的思路,主要就是考察逻辑的严谨性,根据题目给出的边界,我们需要控制好上下左右边界,让指针在该范围内进行持续输出,代码如下:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> arr(n,vector<int>(n));
int row=0,col=0,rowMax=n-1,colMax=n-1;
int sum=1;//输入arr中的元素
while(sum<=n*n)//循环条件
{
for(int i=col;i<=colMax;i++)//上行
{
arr[row][i]=sum++;
}
row++;
for(int i=row;i<=rowMax;i++)//右列
{
arr[i][colMax]=sum++;
}
colMax--;
if(row<rowMax)//判断是否还有行需要输出
{
for(int i=colMax;i>=col;i--)//下行
{
arr[rowMax][i]=sum++;
}
rowMax--;
}
if(col<colMax)//判断是否还有列需要输出
{
for(int i=rowMax;i>=row;i--)//左列
{
arr[i][col]=sum++;
}
col++;
}
}
return arr;
}