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

977. 有序数组的平方

思路1

平方+排序

思路2

双指针

  1. 因为有负数的存在,所以负数的平方变为正数后,有可能是最大的。
  2. 所以最大的数只可能在两边。
  3. 所以两个指针分别指向两边,然后新建一个数组,从后往前给数组赋值即可。

代码

vector<int> res(nums.size(),0);
        int i = 0, j = nums.size()-1,k=nums.size()-1;
        while(i<=j){
            if(nums[i]*nums[i]>nums[j]*nums[j]){
                res[k--]=nums[i]*nums[i];
                i++;
            }else{
                res[k--]=nums[j]*nums[j];
                j--;
            }
        }

        return res;

209. 长度最小的子数组

思路1:暴力

这道题首先可以用两个for循环暴力求解,两个for循环,两个指针一前以后也可以表示区间。然后进行求解。

思路2:滑动窗口

滑动窗口的核心要点就是首先要满足条件,满足条件后开始改变。

  1. 一开始使用for循环求和,直到满足条件。
  2. 之后开始改变,依次删除第一个元素,直到再次不满足条件。
  3. 重复第一步。
class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX;
        int sum = 0; // 滑动窗口数值之和
        int i = 0; // 滑动窗口起始位置
        int subLength = 0; // 滑动窗口的长度
        for (int j = 0; j < nums.size(); j++) {
            sum += nums[j];
            // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
            while (sum >= s) {
                subLength = (j - i + 1); // 取子序列的长度
                result = result < subLength ? result : subLength;
                sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

59 螺旋矩阵 II

要点:

  1. 计算每条边横纵坐标的变化规律。
  2. 计算循环的圈数。
  3. 循环。

注意事项:

  1. 每条边循环的时候需要恒定起始位置。
  2. 边界的地方每次循环都会发生变化

代码

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> a(n, vector<int>(n, -1));
        int startx = 0, starty = 0, i = 0, j = 0, count = 1, offset = 1;
        int total = n / 2;
        while (total--) {
            for (j = starty; j < n - offset; j++) {
                a[startx][j] = count++;
                cout << a[i][j] << " ";
            }
            cout << endl;
            for (i = startx; i < n - offset; i++) {
                a[i][j] = count++;
                cout << a[i][j] << " ";
            }
            cout << endl;
            for (; j > starty; j--) {
                a[i][j] = count++;
                cout << a[i][j] << " ";
            }
            cout << endl;
            for (; i > startx; i--) {
                a[i][j] = count++;
                cout << a[i][j] << " ";
            }
            cout << endl;
            startx++;
            starty++;
            offset++;
        }
        if (n % 2 == 1) {
            a[n / 2][n / 2] = n * n;
        }
        return a;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值