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

题目:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

双指针法思路:

平方后的数组呈现出先下降后递增的趋势。很明显数组中间元素的数值小,数组两边的数值大。可以考虑从两边向中间查找。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int left = 0;
        int right = nums.size() - 1; // 右闭区间
        vector<int> nnums;

        while(left <= right){
            if(nums[left] * nums[left] <= nums[right] * nums[right]){  // 如果右边大,将右边加入容器,右边界减一
                nnums.push_back(nums[right] * nums[right]);
                right--;
            }else{
                nnums.push_back(nums[left] * nums[left]);  // 如果左边大,将左边加绒容器,左边界加一
                left++;
            }
        }
        std::reverse(nnums.begin(), nnums.end());  // 逆序
        return nnums;
    }
};

参考答案:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& A) {
        int k = A.size() - 1;
        vector<int> result(A.size(), 0);
        for (int i = 0, j = A.size() - 1; i <= j;) { // 注意这里要i <= j,因为最后要处理两个元素
            if (A[i] * A[i] < A[j] * A[j])  {
                result[k--] = A[j] * A[j];
                j--;
            }
            else {
                result[k--] = A[i] * A[i];
                i++;
            }
        }
        return result;
    }
};

我用的while循环,而参考答案用的for循环;同时参考答案使用了参数k完成了逆序的操作。

题目:给定一个含有 n 个正整数的数组和一个正整数 target ;找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

滑动窗口法:

通过动态维护一个窗口,实现在线性时间内找到满足特定条件的子数组

步骤:

1 初始化窗口:设置两个指针 left 和 right ,他们表示窗口的左边界和右边界。开始时,窗是空的,即 left=right=0

2 移动右边界:不断增加 right ,直到当前窗口的元素之和大于等于给定的值,或者 right 达到数组的末尾。在这个过程中,窗口的宽度逐渐增加

3 缩小左边界:一旦窗口内元素之和大于等于给定值,开始尝试缩小窗口的左边界,即增加 left ,直到窗口内的元素和小于给定的值。在这个过程中,尽量保持窗口的宽度变小

4 重复2合3:重复以上步骤,直到 right 达到数组的末尾。在整个过程中,动态维护窗口,找到满足条件的子数组。

class Solution {
public:
    int minSubArrayLen(int target, 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(sum >= target){
                sublength = j - i + 1;
                result = result < sublength ? result : sublength;
                sum -= nums[i];
                i++;
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

这里将result设置成为一个最大的值,作用是:数值改变说明result有被赋值

题目:给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

将矩阵看成“口”由字形组成,最后根据n的奇偶来判断是否添加中心点。

class Solution {
public:
    vector<std::vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n, vector<int>(n, 0));
        int m = n;
        int count = 1;
        for (int offset = 0; offset < n / 2; offset++) {
            for (int i = 0; i < m - 1; i++) {
                result[offset][offset + i] = count;
                count++;
            }
            for (int i = 0; i < m - 1; i++) {
                result[offset + i][offset + m - 1] = count;
                count++;
            }
            for (int i = 0; i < m - 1; i++) {
                result[offset + m - 1][offset + m - 1 - i] = count;
                count++;
            }
            for (int i = 0; i < m - 1; i++) {
                result[offset + m - 1 - i][offset] = count;
                count++;
            }
            m -= 2;
        }
        if (n % 2 != 0) {
            result[n / 2][n / 2] = count;
        }
        return result;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值