代码随想录算法训练营第二天| 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II
977. 有序数组的平方
今天做的力扣题目,由于vector数组的初始化错误,debug了半天才发现
所以开篇就将初始化的方法写出来
vector初始化
1.创建一个大小为100的空数组
vector<int>A(100);
2.创建一个大小为100的数组,并赋予初值1
vector<int>A(100,1);
3.将数组Bcopy给数组A
vector<int>A(B);
4.将数组B的切片(此处是前三个)赋值给数组A
vector<int>A(B.begin(),B.begin+3);
5.与4相似,将数组B的B[0]-B[7]赋值给A
int B[7]={0,1,2,3,4,5,6,7};
vector<int> A(B,B+7);
对于该问题,数组是非递减数组,由于可能存在负数,因此数组各个元素平方后,负数可能
会变成更大的正数,因此平方后的数组会变成先递减再递增(如果没有负数,我们认为递减
个数为0,没有正数则认为递增个数为0)
由昨天刷题的经历,我们不难联想倒可以利用双指针min与max,从两端向中间遍历,当两个指针碰头时,遍历结束
创建一个新的数组arr,当原数组
nums【min】*nums【min】<nums【max】*nums【max】
我们就令arr的最后一个元素等于nums【min】*nums【min】
直至结束
因此,我们得到代码
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums)
{
int size = nums.size()-1;
int max = size;
vector<int>arr(size+1);
int min = 0;
while(min<=max)
{
if(nums[min]*nums[min]<=nums[max]*nums[max])
{
arr[size] = nums[max]*nums[max];
max--;
}
else
{
arr[size] = nums[min]*nums[min];
min++;
}
size--;
}
return arr;
}
};
209.长度最小的子数组
由于要求的最小的连续子数列长度,因此我们想到滑动窗口,定义初始的两个指针,分别指着左右窗口,当窗口元素不满足时,右指针向右移动,满足条件时,如果max-min<len,则重置len=max-min,并且让左指针移动,试试能不能缩减窗口大小。
当min<=size时,终止滑动
代码如下:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int size = nums.size();
int min = 0;//定义起始的左窗口
int max = 0;//定义起始的右窗口
int sum = 0;//定义此刻的窗口的元素和
int len = size+1;//初始化窗口大小,定义为元素个数加一,当存在满足的窗口时进行更改,不存在时返回零
while(min<size)//左窗口小于元素下标,继续遍历
{
if(sum<target)
{
if(max == size)//元素和小于目标值,且右窗口到达最右端,则终止
break;
sum += nums[max];//右窗口未到达最右端,向右滑动
++max;
}
else
{
if(max-min<len)//此刻窗口大小小于之前的大小,则赋予它新的值
len = max-min;
sum-=nums[min];//左窗口向右滑动
++min;
}
}
if(len ==size+1)//len还等于初始值,即不存在满足条件的窗口
return 0;
return len;
}
};
977. 有序数组的平方
首先,我们得学会定义一个vector的二维数组
进入二维数组之前,我们先看看一维数组的定义
vector<int>arr(5,0)
其中,int是类型,arr为数组的名称,5代表大小,0是初始化的元素全为零
因此,仿照上述初始化,我们可以得到
vector<vector<int>> arr(n, vector<int>(n, 0));
其中,vector<int>是类型,即一个大的vector里面装的元素是一个个数组
这些数组的类型是vector<int>
arr是数组名,n是数组大小
vector<int>(n,0)代表初始化的元素是一个个值为0的数组。
,
显然,这道题很难想出简便的算法去解决,因此只能进行一圈圈的遍历
而对于每一圈,我们都可以分为四个遍历,即最上面一行,最右侧的一列,最下面的一行以及最左侧的一列。
即如图所示,定义最小和最大遍历指针,每次循环都遍历一圈指针
每一圈之后。令
++min;–max;
即可一圈圈访问所有位置。
需要注意的是,我们写的循环条件是min<max
因此,当n为奇数时,不妨令n等于1,此刻是无法进去循环的,即最后一个位置无法访问,因此,我们需要特别给arr【n/2】【n/2】进行赋值。
令arr[n/2][n/2] = n*n;
代码如下:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> arr(n, vector<int>(n, 0));
int min = 0;
int max = n-1;
int num = 0;
while(min<max)
{
int ii;
for(ii = min;ii<max;ii++)
arr[min][ii]=++num;
for(ii = min;ii<max;ii++)
arr[ii][max]=++num;
for(ii = max;ii>min;ii--)
arr[max][ii]=++num;
for(ii = max;ii>min;ii--)
arr[ii][min] = ++num;
min++;max--;
}
if(n%2)
arr[n/2][n/2]=n*n;
return arr;
}
};
总结,今日收获
vector的初始化,vector二维数组的定义。