代码随想录37期训练营打卡第二天 (数组)

977. 有序数组的平方

暴力解法(简单 时间复杂度o(n*logn))

比较简单,这边就是for循环遍历然后放入新数组,最后排序一下

双指针(o(n))

思路:

数组大的平方和位于数组两端,设置左右指针向中间遍历。

每次将得到较大的平方和放入结果数组中,结果数组指针指向数组末尾。

将有较大平方和的指针向中间靠近(左指针+1or右指针-1)当左指针大于右指针时退出循环。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
     int k =nums.size()-1;//定义新数组指针
     vector<int> result(nums.size(),0);//创建一个新数组,大小为nums的size,数值全部为0
     int i =0,j=nums.size()-1;//设置两端指针向中间遍历,原数组平方和大数在两端
     while(i<=j){//当i<=j时 数组元素还未遍历完成
        if(nums[i]*nums[i] < nums[j]*nums[j]){//当i平方和小于j平方和,则左数平方小于右数,右数平方放入结果数组中,右指针-1;
            result[k--] = nums[j]*nums[j];
            j--;
        }else{//当左平方和大于或等于右平方和,则将左数放入结果数组中,左指针+1
            result[k--] =nums[i]*nums[i];
            i++;
        }
     }
     return result;
    }
};

209. 长度最小的子数组

滑动窗口(o(n))

一个for循环

设置初始最终结果res:取最大值(int result = INT32_MAX;)

设置起始位置和终止位置 (int i = 0; // 滑动窗口起始位置,终止位置在for循环当中向右遍历)

设置滑动窗口的总和(int sum =0;)

设置滑动窗口长度( int subLength = 0; // 滑动窗口的长度)

终止位置j 向数组右边滑动 (for循环)

当出现序列数相加大于等于target 则取子序列长度并更新res(while)

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
    int res = INT32_MAX;//结果值设置为一个最大值
    int sum =0;//数组当前窗口的累加值
    int i=0;//初始位置
    for(int j =0;j<nums.size();j++){
        sum += nums[j];
        //这里使用while 每次更新i(起始位置) 并不断比较子序列是否符合条件
        while(sum >= target){
            int sublength = (j - i +1);//大于目标值的子序列的长度
            res = min(res,sublength);//取最小长度
            sum -= nums[i++];//取到大于等于目标值的子序列后初始位置i就要更新位置(向前+1),同时sum要减去nums[i]的值在进行判断当前序列
                             //是否大于等于target 
        }
    }
    return res == INT32_MAX ?0:res;//返回值如果res没有被赋值则不存在子序列返回0,如果被赋值则返回res最小子序列长度
    }
};

 

59. 螺旋矩阵 II

模拟(o(n2))

思路:一条边一条边模拟

设置初始位置sx,sy,

设置一共要循环多少圈(loop = n/2)

设置给矩阵每个位置赋值(count)

当n为奇数时需要对矩阵中心单独赋值 (mid =n/2)

while循环 :当loop不等于0时表示还有圈圈

        设置i,j为初始位置sx,sy

        上边:从左到右列变换,左闭右开每条边的最后一个位置不遍历(;j<n-offset;j++)循环中赋值res[i] [j] = count ++

        右边:从上到下行变换,左闭右开每条边的最后一个位置不遍历(;i<n-offset;i++)

        下边:从右到左列变换,左闭右开每条边的最后一个位置不遍历

(;j>sy;j--)

        左边:从下到上行变换,左闭右开每条边的最后一个位置不遍历

(;i>sx;i--)

        (注意:这里的循环中i,j不断变换 所以不需要赋值)

        循环一圈结束开始下一圈时更新初始位置(sx ++,sy++)

        控制每行遍历的长度(offset+=1)

        特殊:当n为奇数时对中间位置单独处理(if(n%2){ //这里的count赋值后不再++

        resmid =count; })

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
     vector<vector<int>> res(n,vector<int>(n,0));//vector容器定义一个二维数组
     int sx =0,sy=0;
     int loop =n/2;//定义循环几圈,当n为3时循环一圈 ,矩阵中间值单独处理
     int count =1;//给矩阵赋值
     int mid = n/2;//矩阵中间的位置
     int offset = 1;//左闭右开 每条边遍历长度
     int i ,j;
     while(loop --){
        i =sx;
        j =sy;
        //下面开始模拟转一圈
        //上边从左到右(左闭右开)
        for(j;j<n - offset;j++){
            res[i][j] = count++;
        }
        //右边从上到下(左闭右开)
        for(i;i<n -offset;i++){
            res[i][j] =count++;
        }
        //下边从右到左
        for(;j>sy;j--){
            res[i][j] =count++;
        }
        //左边从下到上
        for(;i>sx;i--){
            res[i][j] =count++;
        }
        //开始下一圈,起始位置缩小1
        sx++;
        sy++;
        //每一圈遍历的长度也要缩小1
        offset+=1;
     }
     //如果n为奇数 单独给最中间的值赋值
     if(n%2){
        res[mid][mid] =count;
     }
     return res;

    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值