cheers �|

冰镇杨梅

园龄:2年2个月粉丝:0关注:0

2023-01-13 00:31阅读: 350评论: 0推荐: 0

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

双指针 lc977 有序数组的平方

如果暴力求解,基本上是将数组每一个元素平方后再排序,主要时间将消耗在排序上,时间复杂度是O(logn), 这种解法忽略了数组本来的顺序信息
通过观察不难发现平方后数组的最大值会存在两边,最小值在中间
使用双指针可以将时间复杂度降到O(n)

自己写的双指针

自己写的这个过分看重对负数和正数的区分,分支判断过多,不够简洁。后面也可以发现,其实对负数和正数提前进行区分是多余的。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> squared(nums.size());
        int npos,pos;
        if (nums[0]<=0){
            npos = 0;
        }
        else{
            npos = -1;
        }
        if (nums[nums.size()-1]>0){
            pos = nums.size()-1;
        }
        else{
            pos = nums.size();
        }

        int i = nums.size()-1;
        while(i > -1){
            if(npos!=-1 && pos != nums.size()){
                if (nums[pos]>=-nums[npos]){
                    squared[i] = pow(nums[pos],2);
                    if (nums[pos-1]>0){
                        pos--;
                    }
                    else{
                        pos = nums.size();
                    }
                }
                else{
                    squared[i] = pow(nums[npos],2);
                    if (nums[npos+1]<=0){
                        npos++;
                    }
                    else{
                        npos = -1;
                    }
                }
                i--;
            }
            else if(npos == -1 && pos != nums.size()){
                squared[i] = pow(nums[pos],2);
                i--;
                    if (pos>0 && nums[pos-1]>0){
                        pos--;
                    }
                    else{
                        pos = nums.size();
                    }
            }
            else if(npos != -1 && pos == nums.size()){
                squared[i] = pow(nums[npos],2);
                i--;
                    if(npos<nums.size()-1 && nums[npos+1]<=0){
                        npos++;
                    }
                    else{
                        npos = -1;
                    }
            }
        }
        return squared;
    }
};

正解双指针

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> squared(nums.size());
        int k = squared.size()-1; //结果数组中的下标
        for(int i=0,j=nums.size()-1;i<=j; ){//i从左到右,j从右到左
            if(pow(nums[i],2)>pow(nums[j],2)){
                squared[k--] = pow(nums[i],2);
                i++;
            }
            else{
                squared[k--] = pow(nums[j],2);
                j--;
            }
        }
        return squared;
    }
};

滑动窗口 lc209 长度最小的子数组

滑动窗口的思路与双指针类似,只是关注的是两个指针区间内所有的元素。

  1. 遍历时应循环迭代的是窗口终点位置
  2. 需要清楚如何动态移动起始点位置

滑动窗口

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int i=0,sum = 0;
        int result_len = INT32_MAX;
        for(int j = 0; j < nums.size(); j++){
            sum += nums[j];
            while(sum>=target){
                int len = j - i + 1;
                result_len = min(len,result_len);
                sum -= nums[i];
                i++;
            }   
        }
        return result_len == INT32_MAX ? 0:result_len; 
    }
};

模拟 lc59 螺旋矩阵II

这道题没什么取巧的方法,这样也只能在时间复杂度为O(n2)下实现。
关键在于对螺旋的模拟要想清楚,边界最好采用统一处理方式,以免写的很乱。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n,vector<int>(n));
        int startx = 0;
        int starty = 0;
        int offset = 1;
        int count = 1;
        int i,j;
        int loop = n/2;
        while(loop--){
            for (i=startx;i<n-offset;i++){
                result[starty][i] = count++;
            }
            for (j=starty;j<n-offset;j++){
                result[j][i] = count++;
            }
            for (;i>startx;i--){
                result[j][i] = count++;
            }
            for (;j>starty;j--){
                result[j][i] = count++;
            }
            startx++;
            starty++;
            offset++;
        }
        if (n%2){
            result[starty][startx] = pow(n,2);
        }
        return result;
    }
};

感觉评论区里的写法也非常简洁

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        int t = 0;      // top
        int b = n-1;    // bottom
        int l = 0;      // left
        int r = n-1;    // right
        vector<vector<int>> ans(n,vector<int>(n));
        int k=1;
        while(k<=n*n){
            for(int i=l;i<=r;++i,++k) ans[t][i] = k;
            ++t;
            for(int i=t;i<=b;++i,++k) ans[i][r] = k;
            --r;
            for(int i=r;i>=l;--i,++k) ans[b][i] = k;
            --b;
            for(int i=b;i>=t;--i,++k) ans[i][l] = k;
            ++l;
        }
        return ans;
    }
};

本文作者:冰镇杨梅

本文链接:https://www.cnblogs.com/frozenwaxberry/p/17048362.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   冰镇杨梅  阅读(350)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起