LeetCode刷题笔记【2】:数组专题-2(有序数组的平方、长度最小的数组、螺旋矩阵)

前置知识

LeetCode刷题笔记【1】:数组专题-1

977. 有序数组的平方

题目描述

在这里插入图片描述

LeetCode链接:https://leetcode.cn/problems/squares-of-a-sorted-array/

解题思路

在头部和尾部分别设置一个指针,比较这两个指针指向的元素的绝对值的大小(或者平方的大小),大的就先进数组,对应的指针移动。
直到两个指针相遇。

代码

// 头尾双指针, 谁的平方大就在前面, 依次移动, 直到二者相等
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n=nums.size();
        int head=0, tail=n-1;
        vector<int> ans(n);
        while(head<=tail){
            int headVal = nums[head]*nums[head];
            int tailVal = nums[tail]*nums[tail];
            if(headVal>=tailVal){
                ans[n-1] = headVal;
                ++head;
            }else{
                ans[n-1] = tailVal;
                --tail;
            }
            --n;
        }
        return ans;
    }
};

209. 长度最小的子数组

题目描述

在这里插入图片描述

LeetCode链接:https://leetcode.cn/problems/minimum-size-subarray-sum/

暴力求解

依次遍历每个元素, 向后生长出一个包括当前元素的子数组, 一直生长到其和>=target, 或者抵达数组结尾, 然后记录其大小, 取最小值

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n=nums.size();
        int ans=INT_MAX, curSize, curVal;
        for(int i=0; i<n; ++i){
            curSize = 0;
            curVal = 0;
            for(int j=i; j<n; j++){
                ++curSize;
                curVal += nums[j];
                if(curVal>=target){
                    ans = min(ans, curSize);
                    break;
                }
            }
        }
        return ans==INT_MAX ? 0 : ans;
    }
};

滑动窗口(双指针)

暴力求解时间复杂度过高, 无法通过.
观察暴力求解法需要反复遍历数组, 思考是否可以一次遍历数组就达到要求.
方法就是构建一个由两个指针组成的窗口, 从头到尾地遍历过去.
在这里插入图片描述

// 先从头开始生长(右移right)一个窗口, 直到满足curVal>=target
// 然后开始左移left, 直到不满足curVal>=target
// 然后继续右移right
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        if(nums[0]>=target)
            return 1;
        int n=nums.size();
        int ans=INT_MAX, curSize=1, curVal=nums[0];
        int left=0, right=1;
        while(left<n && right<n){
            curVal += nums[right];
            curSize++;
            while(curVal>=target){
                ans = min(ans, curSize);
                curVal -= nums[left];
                curSize--;
                left++;
            }
            right ++;
        }
        return ans==INT_MAX ? 0 : ans;
    }
};

59. 螺旋矩阵II

题目描述

在这里插入图片描述

LeetCode链接:https://leetcode.cn/problems/spiral-matrix-ii/

思路

对于模拟类的题目, 或许存在简便做法, 但是大部分情况都是他怎么说你怎么做.
这一题的难点在于厘清和确定循环的边界和过程.

把每一圈的遍历抽出来, 发现每次都是从[startX, startY]处开始, 然后走四个边.
于是每一圈都递增startX和startY, 并且用递增的offset来帮助做遍历.

同时要注意每一个边的边界, 左闭右开
在这里插入图片描述

代码

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> ans(n, vector<int>(n));
        int curVal=1, target=n*n, startX=0, startY=0, offset=1, loop=n/2;
        while(loop--){
            int y=startY;
            int x=startX;
            for(y=startY; y<n-offset; ++y){
                cout << "1 " << x << " " << y << " " << curVal << endl;
                ans[x][y] = curVal++;
            }
            for(x=startX; x<n-offset; ++x){
                cout << "2 " << x << " " << y << " " << curVal << endl;
                ans[x][y] = curVal++;
            }
            for(; y>startY; y--){
                cout << "3 " << x << " " << y << " " << curVal << endl;
                ans[x][y] = curVal++;
            }
            for(; x>startX; x--){
                cout << "4 " << x << " " << y << " " << curVal << endl;
                ans[x][y] = curVal++;
            }
            startX++;
            startY++;
            offset++;
        }
        if(n%2){
            ans[n/2][n/2] = curVal;
        }
        return ans;
    }
};

总结

多指针的方法确实好用, 关键是要对数组的操作有清晰明确的思路和概念.
同时哟啊注意各种边界情况.

本文参考:
977.有序数组的平方
209.长度最小的子数组
59.螺旋矩阵II

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值