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

文章目录

  • 前置知识
  • 977. 有序数组的平方
    • 题目描述
    • 解题思路
    • 代码
  • 209. 长度最小的子数组
    • 题目描述
    • 暴力求解
    • 滑动窗口(双指针)
  • 59. 螺旋矩阵II
    • 题目描述
    • 思路
    • 代码
  • 总结

前置知识

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

977. 有序数组的平方

题目描述

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

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刷题笔记【2】:数组专题-2(有序数组的平方、长度最小的数组、螺旋矩阵)_第2张图片

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刷题笔记【2】:数组专题-2(有序数组的平方、长度最小的数组、螺旋矩阵)_第3张图片

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

思路

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

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

同时要注意每一个边的边界, 左闭右开
LeetCode刷题笔记【2】:数组专题-2(有序数组的平方、长度最小的数组、螺旋矩阵)_第4张图片

代码

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

你可能感兴趣的:(LeetCode刷题笔记,leetcode,笔记,矩阵,算法,c++,经验分享)