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

Leetcode 977 有序数组的平方
思路:可以用暴力解法,将数组中的数都平方后再排序,时间复杂度是O(nlogn),可以用双指针进行优化,优化后时间复杂度是O(n)
因为数组中有负数存在,且数组是有序的,则平方后数组最大值一定在数组两端中,定义两个指针,一个指向数组第一个元素,一个指向数组最后一个元素,比较两个指针对应的数大小,大的数即为新数组中最大的数,放在最后一个,然后指针移动,继续比较两个指针所指的数,得到第二大的数,放在倒数第二个。以此类推,直到两个指针相遇,要注意循环的终止条件是i<=j,两指针相遇时所指的数也要放入新数组

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> res(nums.size()); //定义一个新数组用来存储平方后的数
        int k=nums.size()-1; //新数组的下标索引
        for(int i=0,j=nums.size()-1;i<=j;){ //i和j就是两个下标指针
            if(nums[i]*nums[i]>nums[j]*nums[j]){
                res[k]=nums[i]*nums[i];
                k--;
                i++; //i指针向右移动
            }
            else{
                res[k]=nums[j]*nums[j];  //这里包含了i和j对应的数相等的情况
                k--;
                j--; //j指针向左移动
            }
        }
        return res;
    }
};

Leetcode 209 长度最小的子数组
思路:使用滑动窗口算法,先找到符合条件的子数组,然后减小数组长度,看是否满足题意,满足题意就继续减小数组长度,直到不满足题意,用res记录数组长度的最小值,并判断res有没有被赋值,没有被赋值就输出0

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int res=INT32_MAX; //初始化为最大值
        int len; //序列长度
        int sum=0; //用来计算当前窗口的数字和
        for(int i=0,j=0;j<nums.size();j++){ //i表示序列起始位置 j表示序列终止位置
            sum+=nums[j];
            while(sum>=target){
                len=j-i+1;
                res=min(res,len); //更新序列长度 找到最小序列长度
                sum-=nums[i];
                i++;
            }
        }
        return res==INT32_MAX?0:res;
    }
};

Leetcode 59 螺旋矩阵II
思路:确定好转圈的逻辑,确保每一条边的赋值规则都是相同的,我这里是左闭右开的规则,即循环中包括每一条边的第一个值,不包括每一条边的最后一个值,先得到转圈数为n/2,然后依次对一圈中的每条边赋值,要注意n为奇数时,要对中间位置单独赋值
每转一圈转圈的起始位置要改变,转圈的边界位置也要改变

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n));  //定义一个二维数组
        int startx,starty;  //定义每一圈的起始坐标
        startx=starty=0;
        int mid=n/2; //n为奇数时中间位置的坐标 n=3时中间位置坐标为(1,1)
        int count=1; //数组元素从1开始
        int i,j;
        int offset=1; //控制每一圈转的长度
        for(int k=0;k<n/2;k++){ //k为转圈数 一共转n/2圈
            i=startx;
            j=starty;
            for(;j<n-offset;j++){
                res[startx][j]=count++;
            } 
            for(;i<n-offset;i++){
                res[i][j]=count++;
            }
            for(;j>starty;j--){
                res[i][j]=count++;
            }
            for(;i>startx;i--){
                res[i][j]=count++;
            }
            startx++;
            starty++;
            offset++;
        }
        if(n%2==1){ //如果n为奇数给中间位置元素单独赋值
            res[mid][mid]=count;
        }
        return res;
    }
};
  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值