代码随想录算法训练营第二天| 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II

代码随想录算法训练营第二天| 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]={01234567};
vector<int> A(B,B+7;
对于该问题,数组是非递减数组,由于可能存在负数,因此数组各个元素平方后,负数可能
会变成更大的正数,因此平方后的数组会变成先递减再递增(如果没有负数,我们认为递减
个数为0,没有正数则认为递增个数为0)

代码随想录算法训练营第二天| 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II_第1张图片
由昨天刷题的经历,我们不难联想倒可以利用双指针min与max,从两端向中间遍历,当两个指针碰头时,遍历结束
代码随想录算法训练营第二天| 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II_第2张图片

创建一个新的数组arr,当原数组
nums【min】*nums【min】 我们就令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 当min<=size时,终止滑动
代码随想录算法训练营第二天| 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II_第3张图片
代码如下:

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的数组。


代码随想录算法训练营第二天| 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II_第4张图片

显然,这道题很难想出简便的算法去解决,因此只能进行一圈圈的遍历
而对于每一圈,我们都可以分为四个遍历,即最上面一行,最右侧的一列,最下面的一行以及最左侧的一列。

代码随想录算法训练营第二天| 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II_第5张图片
即如图所示,定义最小和最大遍历指针,每次循环都遍历一圈指针
每一圈之后。令
++min;–max;
即可一圈圈访问所有位置。
需要注意的是,我们写的循环条件是min 因此,当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二维数组的定义。

你可能感兴趣的:(C++,leetcode,算法,矩阵,leetcode,数据结构,c++)