day2: 977. 有序数组的平方、209.长度最小的子数组 、59.螺旋矩阵II

文章讲述了如何解决三个编程问题:对有序数组求平方并保持非递减排序,寻找满足条件的连续子数组的最小长度,以及生成顺时针螺旋排列的矩阵。给出了对应的解答思路和C++代码实现,涉及时间复杂度分析。
摘要由CSDN通过智能技术生成

977. 有序数组的平方

题目:

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

解答思路:

数组本身有顺序,对数组平方之后是一个数值中间小,两边大的数组,考虑到如果从两边开始,用两个指针向中间遍历,相当于从大到小遍历这个数组,最后两个指针相遇的时候一定遍历完了这个数组,所以可以考虑合理设计,从大到小遍历数据,然后从后往前排列进新数组,这样就得到了题目要求的答案。

代码如下:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int size = nums.size();
        vector<int> nums2(size,0);
        int left=0,right = size-1;
        int cnt=0;
        while(left!=right){
            cnt++;
            int ll = nums[left]* nums[left];
            int rr = nums[right]* nums[right];
            if(ll>rr){
                nums2[size-cnt] = ll;
                left++;
            }
            else{
                nums2[size-cnt] = rr;
                right--;
            }
        }
        nums2[0] = nums[right]*nums[right];
        return nums2;
    }
};

209.长度最小的子数组

题目:

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组

 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

解答思路:

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

用两层for循环遍历原数组,第一层for循环确定连续子数组的起点位置,第二层for循环确定其最小终点位置,当找到第一个满足条件的子数组时,即可退出循环。然后再对以后每一个元素作为子数组起点的所有情况进行搜索。将中间结果记录最小的。遍历完成之后就得到了结果。

2. 滑动窗口法O(n^2)         时间复杂度:O(n)

通过维护一个窗口,窗口范围表示满足题目条件的子数组,使用窗口遍历数组,最后记录最小的窗口长。

具体做法是让窗口右指针更快的遍历,遍历完整个数组,就能,窗口左指针负责缩小窗口直到最小满足题意。

    int minSubArrayLenLeftFast(int target, vector<int>& nums) {
        int mlen=INT32_MAX, size=nums.size();
        int wLeft=0, wRight=0;//初始化窗口指针
        int wSum=0;
        for(int wRight=0; wRight<size; wRight++){
            wSum+=nums[wRight];
            while(wSum>=target){
                int lml = wRight-wLeft+1;
                mlen = std::min(lml,mlen);
                wSum-=nums[wLeft];
                wLeft++;
            }
        }
        return mlen==INT32_MAX ? 0: mlen;
    }

代码结构为:

for(窗口右指针从0开始遍历){

        1.(右指针变动后)更新Sum(增大);

           while(Sum满足题意){

               2. 更新(初始化)最小窗长;

               3.左指针左移(窗口右缩) :

                        3.1 Sum值减少,

                        3.2 且Left指针移动
        }

}

4. 遍历完成后,返回记录到的最小窗长,若没有记录到,则返回0;

59. 螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,0));
        int loop=n/2;
        int offset = 1;
        int startX=0, startY=0;
        int i,j;
        int count=1;
        while(loop--){
            i=startX;
            j=startY;
            for(;j<n-offset;j++){
                res[i][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++;
            }
            //更新下一轮参数
            offset++;
            startX++; 
            startY++;
        }
        if(n%2==1) res[n/2][n/2] = count;
        return res;
    }
};

关键:确定循环不变量,跟踪更新坐标位置【)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值