代码随想录day2:数组part02(有序数组的平方 ,长度最小的子数组 ,螺旋矩阵II,数组章节总结)

文章介绍了四种与数组操作相关的算法:暴力方法对有序数组求平方并排序,双指针法解决长度最小子数组问题,滑动窗口优化,以及螺旋矩阵II的生成。着重分析了不同方法的时间复杂度,尤其是滑动窗口法带来的效率提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组part02

一、有序数组的平方

法一:暴力,先把每个元素平方再排序,时间复杂度O(n + nlogn)

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        for(int i=0;i<nums.size();i++) nums[i]*=nums[i];

        sort(nums.begin(),nums.end());
        return nums;
    }
};

法二:双指针,时间复杂度O(n)

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int k=nums.size()-1;
        vector<int> res(nums.size(),0);
        for(int i=0,j=nums.size()-1;i<=j;)
        {
            if(nums[i]*nums[i]<nums[j]*nums[j])
            {
                res[k--]=nums[j]*nums[j];
                j--;
            }
            else
            {
                 res[k--]=nums[i]*nums[i];
                 i++;
            }
        }
        return res;
    }
};

二、长度最小的子数组

法一:暴力,时间复杂度:O(n^2),空间复杂度:O(1)

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int res=INT32_MAX; // 最终结果
        int sum=0; // 子序列的数值之和
        int subLength=0; // 子序列长度
        for(int i=0;i<nums.size();i++)
        {
            sum=0;
            for(int j=i;j<nums.size();j++)
            {
                sum+=nums[j];
                if(sum>=target)
                {
                    subLength=j-i+1;
                    res=res<subLength?res:subLength;
                    break;
                }
            }
        }

        return res==INT32_MAX?0:res; 
    }
};

法二:滑动窗口,时间复杂度:O(n),空间复杂度:O(1)

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int res=INT32_MAX;
        int i=0; // 滑动窗口起始位置
        int sum=0; // 窗口内元素的和
        for(int j=0;j<nums.size();j++)
        {
            sum+=nums[j];
            while(sum>=target)
            {
                int subLength=j-i+1; // 取子序列长度
                res=res<subLength?res:subLength;
                sum=sum-nums[i];
                i++; // 更新i,以保证取的长度最小
            }
        }

        return res==INT32_MAX?0:res;
    }
};

为什么时间复杂度是O(n)。
不是for里放一个while就是O(n^2), 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。

三、螺旋矩阵II

类似二分的思想,控制循环不变量,维护的区间始终为左闭右开
时间复杂度 O(n^2): 模拟遍历二维矩阵的时间
空间复杂度 O(1)

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,0)); // 初始化一个二维数组
        int startx=0,starty=0; // 定义每循环一个圈的起始位置
        int loop=n/2; // 有几个圈
        int mid=n/2; // n为奇数时的矩阵的中间位置
        int offset=1; // 需要控制每条边的遍历长度,每循环一圈右边界就收缩一位
        int count=1; // 用来给矩阵中每一个空格赋值
        int i,j;
        while(loop--)
        {
            i=startx;
            j=starty;

            // 下面四个for循环就是模拟转了一圈
            // 模拟填充上行从左到右(左闭右开)
            for(;j<n-offset;j++) res[i][j]=count++;

            // 模拟填充右列从上到下(左闭右开)
            for(;i<n-offset;i++) res[i][j]=count++;

            // 模拟填充下行从右到左(左闭右开)
            for(;j>startx;j--) res[i][j]=count++;

            // 模拟填充左列从下到上(左闭右开)
            for(;i>startx;i--) res[i][j]=count++;

            // 下一圈开始后,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
            startx++;
            starty++;

            // offset 控制每一圈里每一条边遍历的长度
            offset++;
        }

        // 若n为奇数,最后还需要给矩阵的中心单独赋值
        if(n%2) res[mid][mid]=count;

        return res;
    }
};

四、数组章节总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值