代码随想录算法训练营第二天| 977有序数组平方、207最小子数组、59螺旋矩阵II。

文章介绍了使用排序和双指针技术解决LeetCode上的编程问题,包括有序数组的平方和寻找最小连续子数组。对于有序数组的平方问题,通过直接平方然后排序或双指针方法优化解决方案;对于长度最小的子数组问题,提出了从暴力解到使用快慢指针的优化思路。
摘要由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]

#思路
● 看到题目的第一想法,直接暴力解+sort排序

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

看完代码随想录之后,可以利用双指针法了,i指向起始位置,j指向终止位置。
定义一个新数组result,和A数组一样的大小。
从大到小排序,让k指向result数组终止位置。
如果A[i] * A[i] < A[j] * A[j] 那么result[k–] = A[j] * A[j];
如果A[i] * A[i] >= A[j] * A[j] 那么result[k–] = A[i] * A[i];

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

209.长度最小的子数组
力扣题目链接
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:
输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。

#思路
● 看到题目的第一想法,两层for循环,第一层for遍历数组,第二层for循环更新数组(一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环 完成了一个不断搜索区间的过程)
PS:因为 他的测试用例是10的9次方,而暴力解的时间复杂度是n的平方,测试用例太多了,所以超时

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;//初始化元素个数
        int subL = 0;//定义字符串元素个数
        int sum=0;//总和
        for(int i = 0;i<nums.size();i++)//起始位置
        {
            int sum = 0;
            for(int j = i;j<nums.size();j++)//结束位置
            {
                sum+=nums[j];//求出队列长度
                if(sum>=target)//发现数组超过就更新
                {
                    subL =j-i+1;//元素个数
                    result = result<subL?result:subL;
                    break;
                }
                
            }
        }
        return result = result==INT32_MAX?0:result;
    }
};

看完代码随想录之后,可以利用快慢指针法,快指针用来寻找新数组的元素(不含目标元素),慢指针用来指向新数组的下标。
用一个快慢指针在for’循环内完成两个for循环的工作。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int sum = 0;
        int subL = 0;//元素长度
        int i=0;
        int result = INT32_MAX;
        for(int j=0;j<nums.size();j++)
        {
            sum+=nums[j];
            while(sum>=target)
            {
                subL = j-i+1;//计算长度
                result = result<subL?result:subL;//获取最小长度
                sum = sum-nums[i];
                i++;
            }
        }
        return result==INT32_MAX?0:result;
    }
};

59.螺旋矩阵II
力扣题目链接
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
● 看到题目的第一想法,一进循环深似海,从此Offer是路人

看完代码随想录之后,注意转圈的逻辑+区间的定义。
每画一条边都要坚持一致的左闭右开的原则,这样这一圈才能按照统一的规则画下来,就像二分法 ,每次分数组保持相对一致的数量。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n, vector<int>(n, 0)); 
        int startx = 0, starty = 0; 
        int offset = 1;  
        int loop = n / 2;
        int mid = n / 2; 
        int count = 1; 
        int i, j; 
        while (loop--) {
            i = startx;  
            j = starty;

            for (j = starty; j < n - offset; j++) result[i][j] = count++; // 填写上边
            for (i = startx; i < n - offset; i++) result[i][j] = count++; // 填写右边
            for (; j > starty; j--) result[i][j] = count++; 
            for (; i > startx; i--) result[i][j] = count++; 
            
            startx++; 
            starty++;

            offset++;
        }

        if (n % 2) result[mid][mid] = count;  
        return result;
    }
};

总结
● 花了6~7个小时,终于把day2任务完成,还有几天出成绩,希望能上岸!
● 今天还学了如果debug,大概就是哪里有错,哪里cout,数组结束!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值