代码随想录第2天|LeetCode 977有序数组的平方||209 长度最小的子数组||59 螺旋矩阵 II

文章概述了在LeetCode中的三个编程问题,涉及数组平方、长度最小子数组和螺旋矩阵II,强调了边界判定、双指针策略以及空间和时间复杂度优化。通过实例展示了C++代码解决这些问题的方法。

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

第一章 数组part02

今日花费时间较多,在第二题的边界判定上消耗时间较多,应多注重细节。

LeetCode 977 有序数组的平方Easy

题目链接: 977 有序数组的平方

思路:1. 考虑到数组可能有负数有正数,它们的平方的大小都是从两边到0逐渐减小,所以可以设置两个指针从两边到中间运动,不断判断指针位置处两个数的大小,将较大的数从后往前放入数组res中。

在这里插入图片描述

完整C++代码如下:

//时间复杂度:O(1)
//空间复杂度:O(1)
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int len=nums.size();
  		int l=0,r=len-1;
        vector<int> res(len);
		while(l<=r){
            if(abs(nums[r])>=abs(nums[l])){
                res[--len]=nums[r]*nums[r--];
                
            }else{
                 res[--len]=nums[l]*nums[l++];
            }
        }
        return res;
    }
};

LeetCode 209 长度最小的子数组

题目链接:209 长度最小的子数组

思路:

  1. 滑动窗口(双指针):由于是求一个长度最小的连续子数组,所以想到使用双指针逐渐缩小范围,但从两边到中间不断缩小,两端指针指向比较大小保留较大值的思路是错误的,原因在于本题局部最大值保留未必全局最优连续子数组保留,如下面若取target为13,即使l为2,仍然要保留r,让l+1
    在这里插入图片描述

    仍然采取双指针的思路,重点是要考虑每种(恰好或多一点)符合条件组合中的最小值*(直接考虑整体而不是两端逐个比较),让两个指针l,r都置于最左边,优先让r右移直到恰好满足target,r停止移动,此时l开始移动直到l,r之间的数组*恰好不满足target,r继续右移,每完成一轮r,l指针移动得到的连续子数组就是所有组合中的一组,通过一个数minLen记录最小长度。

    注:双指针(滑动窗口)的思路是暴力解思路的简单优化,就是找所有的可能组合,但1. 滑动窗口可以实时的用两个指针维护结果,而暴力双for需要不断重新计算sum。2. 一些可能不需要再进行计算,双for仍会从头开始依次遍历0,双指针中l会直接后移到5。

在这里插入图片描述

完整C++代码如下:

//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {   
public:
    int minSubArrayLen(int target, vector<int>& nums) {
		int l=0,r=0;
        int sum=nums[0];//默认直接存第一个数
        int min_len=nums.size()+1;
		while(1){
            if(sum<target){
                if(r>=nums.size()-1){//已经到最后一位了,这时候如果再次进入sum<target条件体,说明要出循环了
                    break;//出口
                }
            	sum+=nums[++r];
            }else{
                if(r-l+1<min_len)min_len=r-l+1;
                sum-=nums[l++];
            }
        }
        if(min_len==nums.size()+1)return 0;
        return min_len;
    }
};

注:注意边界条件,尤其是r=nums.size()-1时,注意出口的位置。

LeetCode 59 螺旋矩阵 II

题目链接:59. 螺旋矩阵 II

思路:

本题思路较为直观,就是将矩阵分为四部分,依据左闭右开的原则,通过设置多个变量和简单for循环来完成此题,如下图

在这里插入图片描述

完整C++代码如下:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
		vector<vector<int>>res(n,vector<int>(n,0));//存储结果的数组
        int loop=n/2;//圈数是边长的1/2
        int EndPosition=n-1;//注意是结束位置而不是当前行长
        int startX=0,startY=0;
        int numNow=1;
        int i,j;
        while(loop--){
            i=startX;//每一圈的起始x与起始y
            j=startY;  
            //上行从左到右
            for(j=startY;j<EndPosition;j++){
                res[i][j]=numNow++;
            }
            //右列从上到下
            for(i=startX;i<EndPosition;i++){
                res[i][j]=numNow++;
            }
            //下行从右到左
            for(;j>startY;j--){
                res[i][j]=numNow++;
            }
            //左列从下到上
            for(;i>startX;i--){
                res[i][j]=numNow++;
            }
            EndPosition--;
            startX++;
            startY++;
        }
        //考虑奇数矩阵最后中心的数也要填充,不用再设置别的数,此时的startX,Y恰好位于此处
        if(n%2){
            res[startX][startY]=numNow;
        }
        return res;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值