打卡第二天:有序数组的平方、长度最小的子数组、螺旋矩阵II

打卡第二天,学习算法的同时回顾SQL和Linux知识。

1、有序数组的平方

题目链接

文章讲解

视频讲解

关键是如何想到用双指针法?原数组有序,结果数组有序,原数组元素平方后,一定是两边大中间逐渐减小。

写码的问题直接随手注释。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int k = nums.size() - 1;
        vector<int> result(nums.size(), 0);//注意此句设置结果数组写法
        for ( int i = 0, j = nums.size() - 1; i <= j ; ){//如果只写i<j,若有中间两数相等,循环会跳出,少更新一个元素
            //i和j的更新都需要一定条件,因此不写在for循环条件中
            //小错误,定义j时不用再写个int;也不要忘了-1
            if ( nums[i] * nums[i] < nums[j] * nums[j] ){
                result[k--] = nums[j]*nums[j];//注意把k--放在这里的写法
                j--;
            }else {
                result[k--] = nums[i]*nums[i];
                i++;
            }
        }
        return result;
    }
};

理解思路应当不难,但想到这个方法和代码细节很重要。养成良好习惯。

2、长度最小的子数组

题目

文章讲解

视频讲解

原理是右边先开始走,然后直到窗口内值的总和大于target,此时就开始缩圈,缩圈是为了找到最小值,只要此时总和还大于target,我就一直缩小,缩小到小于target为止在这过程中不断更新最小的长度值,然后右边继续走,如此反复,直到右边碰到边界。

关键是1、先固定移动右指针,判断条件是否可以收缩左指针算范围。2、在双指针中如何移动起始位置的指针?起始位置的指针要持续向后移动,更新滑动窗口。3、里面不能有负数。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = nums.size();//应设为INT32_MAX最大值
        int i = 0;
        int sum = 0;
        int subl = 0;
        for (int j = 0; j < nums.size(); j++){
            sum += nums[j];
            while (sum >= target){
                //用while不用if因为需要不断更新起始指针
                subl = j - i + 1;
                result = result < subl ? result : subl; //注意这里的比较大小写法
                sum = sum - nums[i];
                i++;//起始指针移动
            }
        }
        return result == nums.size() ? 0 : result;//注意这句的写法
    }
};

错误点:在最后返回结果时应考虑到没有满足条件的窗口的情况

3、螺旋矩阵II

题目

文章讲解

视频讲解

第一个中等题

原理是坚持循环不变量原则,让每种(即填充上部右部下部左部的哪部)填充操作保持相同样式的循环:通过offset预留位置。按上右下左的顺序依次填入递增的数。要留意while何时退出。

一些注意点随手写在注释里:

每一圈循环的起始横下标,在转完一圈以后更新

每一圈循环的起始纵下标,在转完一圈以后更新

每圈上部,从左到右递增,留offset个位置,所以填到下标为n-offset为止

每圈右部,从上到下递增,留offset个位置,所以填到下标n-offset为止

每圈下部,从右到左递增,留offset个位置,所以填到下标offset-1或startx为止

每圈左部,从下到上递增,留offset个位置,所以填到下标offset-1或starty为止

每次循环初始位置下标+1

每次循环预留位置下标+1

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> nums(n, vector<int>(n, 0));//初始化二维数组矩阵
        int startx = 0;//每一圈循环的起始横下标,在转完一圈以后更新
        int starty = 0;//每一圈循环的起始纵下标,在转完一圈以后更新
        int offset = 1;//转的第几圈,边缘就要空出几个位置
        int loop = n / 2;
        int count = 1;
        int i,j;
        while (loop --){
            i = startx;
            j = starty;//提前声明,防止在for循环内声明时作用不到外部
            //每圈上部,从左到右递增,留offset个位置,所以填到下标为n-offset为止
            for(j; j < n - offset; j++){
                nums[startx][j] = count++;//i不变,按j递增赋值count
            }
            //每圈右部,从上到下递增,留offset个位置,所以填到下标n-offset为止
            for(i; i < n - offset; i++){
                nums[i][j] = count++;//j不变,按i递增赋值count
            }
            //每圈下部,从右到左递增,留offset个位置,所以填到下标offset-1或startx为止
            for(;j > offset - 1; j--){
                nums[i][j] = count++;//i不变,按j递减赋值count
            }
            //每圈左部,从下到上递增,留offset个位置,所以填到下标offset-1或starty为止
            for(;i > offset - 1; i--){
                nums[i][j] = count++;//j不变,按i递减赋值count
            }
            startx++;//每次循环初始位置下标+1
            starty++;//每次循环初始位置下标+1
            offset++;//每次循环预留位置下标+1
        }
        //如果n是奇数,需要填充中心位置的元素,但要注意此时的数组下标
        if(n%2 == 1){
            nums[startx][starty] = count;// 或者先预设mid=n/2,填充的就是nums[mid][mid],例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
        }
        return nums;
    }
};

错误点:1、基础的参数声明,要明确参数作用的范围。2、注意while条件的写法。3、n是奇数的情况,中心位置填充时数组下标应该怎么样填。

明天继续加油。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值