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

本文介绍了LeetCode中的三个问题:有序数组的平方使用双指针优化求解,长度最小的子数组通过滑动窗口实现,螺旋矩阵II则通过控制小人或墙壁的移动来构造。展示了高效的算法策略和时间/空间复杂度分析。
摘要由CSDN通过智能技术生成

 目录

一、977. 有序数组的平方

二、209. 长度最小的子数组

三、59. 螺旋矩阵 II


一、977. 有序数组的平方

题目链接:力扣

文章讲解:代码随想录

视频讲解: 双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

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

代码:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int left = 0, right = nums.size()-1;
        vector<int> ans(nums.size(),0);
        int numb = nums.size()-1;
        int leftvalue = nums[left]*nums[left];
        int rightvalue = nums[right]*nums[right];
        while(left <= right){
            while(left < right && leftvalue > rightvalue)
            {
                ans[numb--] = leftvalue;
                left++;
                leftvalue = nums[left] * nums[left];
            }
            while(left <= right && leftvalue <= rightvalue)
            {
                ans[numb--] = rightvalue;
                right--;
                if(left > right) break; //考虑循环结束情况
                rightvalue = nums[right] * nums[right];
            }
        }
        return ans;//10:45
    }
};

时间复杂度O(n)                                                       空间复杂度:O(1)

⏲:10:45

总结:头尾指针相向移动可同时处理首尾数据减少时间复杂度和操作量,但是无法在原数组上直接进行操作。

二、209. 长度最小的子数组

题目链接:力扣

文章讲解:代码随想录

视频讲解:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili

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

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

代码:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int sum = 0;
        int numb = 0;
        int min_numb = INT_MAX;
        for(int begin = 0, end = 0; end < nums.size(); end++)
        {
            sum += nums[end];
            numb++;
            while (sum >= target)
            {
                if(min_numb > numb)
                {
                    min_numb = numb;
                } 
                sum -= nums[begin++];
                numb--;

            }
        }
        
        return min_numb == INT_MAX ? 0 : min_numb;//7:53
    }
};

时间复杂度:O(n)                                                                         空间复杂度:O(1)

⏲:7:53

总结:注意三点:1.滑动窗口内的数据情况 2.滑动窗口结束情况 (一个指针单向递增为循环)3.滑动窗口的两个指针更新情况

三、59. 螺旋矩阵 II

题目链接:力扣

文章讲解:代码随想录

视频讲解:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili

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

代码:

法一:关注每个点的可走情况,制作一个方向器(方向呈顺时针),模拟走格子,当下一个位置符合条件且未走过时,即为可走位置。

法二:控制每次走的极限情况,当每个方向行走达到极限时,更改方向。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
    /*法一:模拟控制小人走格子
    class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
    vector<vector<int>> ans(n,vector<int>(n,0)),fx={{0,1},{1,0},{0,-1},{-1,0}};
    int next_x=0,next_y=0,f=0;
    int x=0,y=0;
    for(int k=1;k<=n*n;k++)
    {
        ans[x][y]=k;
        for(int t=0;t<4;t++)
        {
            next_x=x+fx[f][0];
            next_y=y+fx[f][1];
            if(next_x>=0 && next_y>=0 && next_x<n && next_y<n && !ans[next_x][next_y])
            {
                x=next_x;
                y=next_y;
                break;
            }
            f=(f+1)%4;
        }
    }
    return ans;//10:41
    }
};*/
    /*法二:控制墙壁*/
    vector<vector<int>> ans(n, vector<int>(n, 0));
    int k=1;
    int x=0,y=0;
    int left=0,right=n-1,top=0,bottom=n-1;//各面墙壁
    while(k<=n*n)//墙推人走
    {   
        for(y=left;y<=right;)//左闭右闭
            ans[top][y++]=k++;
        if(k>n*n) break;
        top++;//走完墙更新
        for(x=top;x<=bottom;)//左闭右闭
            ans[x++][right]=k++;
        if(k>n*n) break;
        right--;//走完墙更新
        for(y=right;y>=left;)//左闭右闭
            ans[bottom][y--]=k++;
        if(k>n*n) break;
        bottom--;//走完墙更新
        for(x=bottom;x>=top;)//左闭右闭
            ans[x--][left]=k++;
        left++;//走完墙更新
    } 
    return ans;
    }
};

时间复杂度O(n^2)                                                       空间复杂度:O(1)

总结:两个方法,操控人与操控墙。

1.操控人 (1)方向器 (2)判断位置的合法性        注意:合法条件的判断

2.操控墙 (1)墙的初值(2)墙的更新        注意:遵循循环不变量原则

个人认为法一模拟行走,更符合题目情况。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值