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

977.有序数组的平方

思路:
1、双指针法,从两头向中间走
2、含有负数,因此两端大,中间小
3、利用for循环进行重复比较,并移动指针
4、创建一个新的数组,把比较后得到的值放新数组里(从大往小,从小往大,都行)
注意:
vector一维数组的初始化方式为vector<int>result(nums.size(), 0);

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        /* 
            1、双指针法,从两头向中间走
            2、含有负数,因此两端大,中间小
            3、利用for循环进行重复比较,并移动指针
            4、创建一个新的数组,把比较后得到的值放新数组里(新数组从大往小,从后往前放)
        */
        int slow = 0;
        int fast = nums.size() - 1;
        vector<int>result(nums.size(), 0);
        for(int i = nums.size() - 1; i >= 0; i--){
            if(nums[slow] * nums[slow] > nums[fast] * nums[fast]){
                result[i] = nums[slow] * nums[slow];
                slow++;
            }else if(nums[slow] * nums[slow] <= nums[fast] * nums[fast]){
                result[i] = nums[fast] * nums[fast];
                fast--;
            }
        }
        return result;
    }
};

209.长度最小的子数组

思路:
1、采用滑动窗口,实际上仍是双指针法
2、双指针相比于暴力解法的优点在于:用一个for循环替代两个for循环
3、若窗口内的和 >= target,则记录此时数组的大小,然后开始往外吐,再次判断
4、用一个值来记录数组大小即可,每次都把小的值替换进去,不用全放数组里再判断 (巧用三目运算符)
5、fast是一定每次都得试探的往右移动的,因此for循环的条件里是fast而不是slow。slow只有满足一定条件才移动,在for循环内部实现即可
6、for循环中fast < nums.size() ,而不是fast < size,后者会由于size = fast - slow + 1得到一个常数,fast就卡死在那了,不动了。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        /*
            1、采用滑动窗口,实际上仍是双指针
            2、用一个for循环替代两个for循环
            3、若窗口内的和 >= target,则记录此时数组的大小,然后开始往外吐,再次判断
            4、用一个值来记录数组大小即可,每次都把小的值替换进去,不用全放数组里再判断
            5、fast是一定每次都得试探的往右移动的,因此for循环的条件里是fast而不是slow
            6、slow只有满足一定条件才移动,在for循环内部实现即可
            7、第5条中,fast的移动是取决于size,而不是nums.size()
            8、第7条说的恰恰相反
        */
        int slow = 0;
        int result = INT_MAX;
        int size = nums.size();
        int sum = 0;
        for(int fast = 0; fast < nums.size(); fast++){
            sum = sum + nums[fast];
            size = fast - slow + 1;
            //cout<< fast <<"轮次" <<" : size = " << size << "sum = " << sum << endl;
            while(sum >= target){
                //size = fast - slow + 1;
                result = result < size ? result : size;
                sum = sum - nums[slow];
                slow++;
                size--;
            }
            
        }
        return result == INT_MAX ? 0 : result;
    }
};

59.螺旋矩阵II

思路:
1、按二分法的区间来转圈,保证逻辑一致就容易分类(1 2 一组, 3 4, 5 6 , 7 8)
2、从数学来讲,1所在位置是(0,0),2在(0,1),以此类推
3、利用for循环,循环赋值
4、但是二维数组咋赋值来着?
5、n分为奇数和偶数。奇数的话中间的点需要单独取(如示例1的数字9),偶数则不需要
6、需要一个可以一直+1的值,用于赋值 (搞个num)

自己写的时候出现的问题:
1、没考虑圈数(loop),光看例题去了,就觉得n = 3就完事了。是错误的
2、我的row 和 column 就是相当于 start_x 和 start_y 专门定义起始位置,每一圈都会变
3、我的index其实和卡哥的offset是一个意思,但我就是只考虑n = 3,所以没有偏移量
4、人家的起始位置是每过一圈过后才改变值的,在for循环里用 i 和 j 初始化成row和column后 用来变化
5、如第2条所说,row 和 column定义转圈的起始位置,因此在第一个for循环里要写result[row][j] = num;才对。若写成result[i][j] = num;则会导致n = 4时赋值位置乱掉,从而出现错误,且其他测试用例也有过不了的,如下图所示:
在这里插入图片描述

注意:
vector二维数组的初始化方式为vector<vector<int>> result(n,vector<int>(n, 0));
这样也行vector<vector<int>> result(n,vector<int>(n));

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        /*
            1、按二分法的区间来转圈,保证逻辑一致就容易分类(1 2 一组, 3 4, 5 6 , 7 8)
            2、从数学来讲,1所在位置是(0,0),2在(0,1),以此类推
            3、利用for循环,循环赋值
            4、但是二维数组咋赋值来着?
            5、n分为奇数和偶数。奇数的话中间的点需要单独取(如示例1的数字9),偶数则不需要

            6、需要一个可以一直+1的值,用于赋值 num 

            没考虑圈数,光看例题去了,就觉得n = 3就完事了。是错误的
            我的row 和 column 就是相当于 start_x 和 start_y 专门定义起始位置,每一圈都会变
            我的index其实和卡哥的offset是一个意思,但我就是只考虑n = 3,所以没有偏移量
            但人家的起始位置是不改变值的,在for循环里用i和j初始化成row和column后用来变化
        */
        vector<vector<int>> result(n,vector<int>(n));//查了一下 应该是这样
        int row = 0;//行
        int column = 0;//列
        int num = 1;
        int i = 0;
        int j = 0;
        int mid = n / 2;
        int offset = 1;
        int loop = n / 2;
        while(loop--){//假设n = 4
            for(j = column; j < n - offset; j++){
                result[row][j] = num;
                num++;
            }//循环结束后i = 0,j = 3(注意,最后还有个j++,所以j = 3
            for(i = row; i < n - offset; i++){
                result[i][j] = num;
                num++;
            }//循环结束后i = 3,j = 3
            for(; j > column; j--){
                result[i][j] = num;
                num++;
            }//循环结束后i = 3,j = 0
            for(; i > row; i--){
                result[i][j] = num;
                num++;
            }//循环结束后i = 0,j = 0

            row++;
            column++;
            offset++;
        }
        
        if(n % 2 == 1){
            result[mid][mid] = num;
        }
        return result;

    }
};
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值