0

「算法刷题」栈运算专项汇总(力扣版)

 1 year ago
source link: https://magicdeveloperdrl.github.io/2022/06/13/%E7%AE%97%E6%B3%95%E5%88%B7%E9%A2%98-%E6%A0%88%E8%BF%90%E7%AE%97%E4%B8%93%E9%A1%B9%E6%B1%87%E6%80%BB-%E5%8A%9B%E6%89%A3%E7%89%88.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

「算法刷题」栈运算专项汇总(力扣版)

Jun 13, 2022 • MRL Liu

本文记录作者刷题过程中与栈相关的题目。

一、设计最小栈

剑指 Offer 30. 包含min函数的栈(中等函数)

155. 最小栈(简单难度)

面试题 03.02. 栈的最小值(简单难度)

class MinStack {
public:
    stack<int> stack1;//正常栈,实现栈的正常功能
    stack<int> stack2;//辅助栈,负责实现min函数,入栈时只入比自己栈顶元素小的元素,出栈时和当前元素相等就出栈
    MinStack() {}
    // 入栈
    void push(int val) {
        stack1.push(val);//正常入栈
        // 如果辅助栈为空或者辅助栈栈顶元素比较大,就入栈
        if(stack2.empty()||stack2.top()>=val)stack2.push(val);
    }
    // 出栈
    void pop() {
        int top=stack1.top();
        stack1.pop();// 正常出栈
        // 如果出栈的元素和辅助栈栈顶元素相等
        if(top==stack2.top()) stack2.pop();
    }
    // 获取栈顶元素
    int top() {
        return stack1.top();//正常的栈顶元素
    }
    // 获取最小值
    int getMin() {
        return stack2.top();//辅助栈的栈顶元素
    }
};

二、验证栈序列

剑指 Offer 31. 栈的压入、弹出序列

946. 验证栈序列(中等难度)

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> stk;
        int i=0;
        for(int x:pushed){
            stk.push(x);
            // 循环检查,如果栈顶元素和出栈队列元素相同就出栈
            // 栈内元素用完就继续加
            while(!stk.empty()&&stk.top()==popped[i]){
                stk.pop();
                i++;
            }
        }
        return stk.empty();
    }
};

三、单调栈

剑指 Offer II 039. 直方图最大矩形面积

84. 柱状图中最大的矩形

class Solution {
public:
    /*本题也是一套经典题目,题目容易理解,难点在于分析什么时候勾勒的矩形面积最大?
    思路:
    假设我们考察其中一个柱子,它所能勾勒出的最大矩形面积由左侧柱子和右侧柱子的高度决定:
    若左柱子的高度>当前考察的柱子高度,则向左扩张一个柱子,直至左侧柱子高度<当前柱子高度||左侧无柱子
    若右柱子的高度>当前考察的柱子高度,则向右扩张一个柱子,直至右侧柱子高度<当前柱子高度||右侧无柱子
    此时最大矩形面积=当前柱子的高度*左右最远柱子间的距离
    单调栈的简单思路讲解:https://blog.csdn.net/Zolewit/article/details/88863970*/
    int largestRectangleArea(vector<int>& heights) {
        int res=0;//最大面积
        int n=heights.size();
        // 在原数组左右两侧添加一个0
        vector<int> height(n+2,0);
        for(int i=1;i<n+1;i++){
            height[i]=heights[i-1];
        }
        stack<int> stk;// 单调栈,保存元素索引
        for(int i=0;i<n+2;i++){
            // 当前入栈元素为height[i],将栈中所有比height[i]大的元素出栈
            while(!stk.empty()&&height[i]<height[stk.top()]){
                // 出栈
                int index=stk.top();
                stk.pop();
                // 此时,height[index]的下一个更小元素是height[i],上一个更小元素是height[stk.top()]
                int hig=height[index];//高=height[index],其随着出栈而不断变化
                int wid=i-stk.top()-1;//宽=[stk.top(),i]=i-stk.top()-1,右边界是定值,左边界是变量
                res =max(res,hig*wid);//完全覆盖第index个柱子的最大矩形的面积
            }
            stk.push(i);
        }
        return res;
    }
};

85. 最大矩形

剑指 Offer II 040. 矩阵中最大的矩形

class Solution {
public:
    /*每一层看作是柱状图,可以套用84题柱状图的最大面积。
    第一层柱状图的高度["1","0","1","0","0"],最大面积为1;
    第二层柱状图的高度["2","0","2","1","1"],最大面积为3;
    第三层柱状图的高度["3","1","3","2","2"],最大面积为6;
    第四层柱状图的高度["4","0","0","3","0"],最大面积为4;*/
    int maximalRectangle(vector<vector<char>>& matrix) {
        if (matrix.size() == 0 || matrix[0].size() == 0) {
            return 0;
        }
        int col = matrix.size();
        int row = matrix[0].size();
        vector<int>heights(row);
        int ans = 0;
        for (int i = 0; i < col; i++) {
            for (int j = 0; j < row; j++) {
                if (matrix[i][j] == '1') {
                    heights[j] += 1;
                } else {
                    heights[j] = 0;
                }
            }
            ans = max(ans, largestRectangleArea(heights));
        }
        return ans;
    }
    int largestRectangleArea(vector<int>& heights) {
        int res=0;//最大面积
        int n=heights.size();
        // 在原数组左右两侧添加一个0
        vector<int> height(n+2,0);
        for(int i=1;i<n+1;i++){
            height[i]=heights[i-1];
        }
        stack<int> stk;// 单调栈,保存元素索引
        for(int i=0;i<n+2;i++){
            // 当前入栈元素为height[i],将栈中所有比height[i]大的元素出栈
            while(!stk.empty()&&height[i]<height[stk.top()]){
                // 出栈
                int index=stk.top();
                stk.pop();
                // 此时,height[index]的下一个更小元素是height[i],上一个更小元素是height[stk.top()]
                int hig=height[index];//高=height[index],其随着出栈而不断变化
                int wid=i-stk.top()-1;//宽=[stk.top(),i]=i-stk.top()-1,右边界是定值,左边界是变量
                res =max(res,hig*wid);//完全覆盖第index个柱子的最大矩形的面积
            }
            stk.push(i);
        }
        return res;
    }
};

「算法刷题」数组之大数相加专项汇总(力扣版)

「算法刷题」深度优先遍历专题汇总(力扣版)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK