leetcode -- 栈总结

栈的相关题目也比较多,这里主要对栈中的easy,top 100 liked qusetions和top interviewquestions做了详细总结。

目录

1.  栈实现队列

2.  队列实现栈

3.  包含min函数的栈

4.  计算算式

5.  给定序列判断出栈顺序是否可行

7. 括号匹配

8.  与二叉树结合,遍历二叉树

9. 求一个区域的题目

10. 嵌套迭代器


1.  栈实现队列

(232. Implement Queue using Stacks, easy)

方法1:用一个栈

方法2:用两个栈

2.  队列实现栈

(225. Implement Stack using Queues, easy)

3.  包含min函数的栈

(155. min stack, easy)

4.  计算算式

(1)  逆波兰表达式(后缀表达式)

(150. Evaluate Reverse Polish Notation,easy)

计算算数表达式,当前是操作数入栈,遇到运算符计算,并将结果保存在栈中

(2) 给出算式,实现简单的计算器

(224.basic calculator, hard) 利用有限状态机实现

(3) 682. Baseball Game, easy

5.  给定序列判断出栈顺序是否可行

思考:一个栈入栈序列1、2、3、4....n, 有多少种出栈序列???

7. 括号匹配

(1){},[],()匹配:  (20. Valid Parentheses, easy)

(2)最长括号匹配():用stack(空间复杂度O(n),时间复杂度O(n))和不用栈deep(空间复杂度O(1),时间复杂度O(2n)=O(n))两种方法,

(start从-1开始,这样用end-start就是[start+1,end]的长度。而不是表示为end-start+1,start=0)

(3)括号匹配[]:(394. Decode String)

思考:对字符串解码,本质上还是要进行括号匹配。Eg. 2[a3[bc]]àabcbcbcabcbcbc, stack str 缓存还没有进行匹配的字符串,stack缓存子串的数量。

8.  与二叉树结合,遍历二叉树

1.    先序遍历:非递归法,(144. Binary TreePreorder Traversal)

思路:将root和左子树节点入栈,并同时放入序列中,直到左子树节点为空,之后栈顶的元素出栈,之后将指针移动到刚出栈节点的right(无论是否有右子树节点),继续。

2. 中序遍历:非递归法,(94.Binary Tree Inorder Traversal)

思路:将root和左子树节点入栈,直到左子树节点为空,之后栈顶的元素出栈,并放入序列中,之后将指针移动到刚出栈节点的right(无论是否有右子树节点),再继续入栈节点和其左子树节点。

3. 后序遍历:非递归法,(145.Binary Tree Postorder Traversal)

思路:先将root入栈,并标记被访问的位置为root,每次从栈中取元素判断是否为叶子节点,或是是否左子树已被访问过且右节点为空,或是右节点已经被访问过,满足上述条件之一表明这是当前要访问的节点,并更新visited,并出栈。其他情况先节点先入栈,再节点入栈。

4. 之字形遍历 103.Binary Tree Zigzag Level Order Traversal

思路:利用两个栈,每次遍历两层,stack1存放正序节点,stack2存放逆序节点

9. 求一个区域的题目

42. Trapping Rain Water, Hard 求存水量

方法1:计算每个柱子左边和右边的最大高度,用min(maxleftHeight, maxrighHeight) - height[i]就是当前第i个柱子可以存放水量

方法2:先取得最高的柱子,将数组分为两部分。分别遍历左右两部分数组,边遍历数据,边计算当前i位置左边或右边的最大高度,

当当前的height小于最大高度maxheight时,表示当前位置能够存放水,计算存水量maxheight-height[i].

方法3:利用辅助的stack,当栈顶元素对应的高度小于当前元素大小,那么计算存水量;当栈顶元素对应的高度大于当前的高度时,那么直接插入元素。

 

leetcode -- 栈总结_第1张图片

 

 

class Solution {
public:
    int trap(vector& height) {
        int waiter = 0;
        stack s; // save idx
        for(int i = 0; i < height.size(); ++i)
        {
                while(!s.empty() && height[s.top()] < height[i])
                {
                    // 凹形计算waiter, (height[s.top()], height[mid], height[i])组成凹形
                    int mid = s.top();
                    s.pop();
                    if(!s.empty())
                    {
                        waiter += (min(height[s.top()], height[i]) - height[mid]) * (i - s.top() - 1);
                    }
                }
                
            s.push(i);
        }
        
        return waiter;
    }
};

85. Maximal Rectangle, Hard 求最大的矩形

方法1:计算高度,在利用栈

方法2:计算高度,左边界,右边界,求面积

 

class Solution {
public:
    int maximalRectangle(vector>& matrix) {
        int res = 0;
        
        int row = matrix.size();
        if(row == 0)  //!!!
            return 0;
        
        int col = matrix[0].size();
        vector> heights(row, vector(col+1, 0)); // col+1是为了计算带有最后一列的矩阵
        
        // 计算高度
        for(int i = 0; i < row; ++i)
        {
            for(int j = 0; j < col; ++j)
            {
                if(matrix[i][j] == '1')
                {
                    heights[i][j] = 1 + (i > 0 ? heights[i-1][j] : 0);
                }
            }
        }
        
        // 计算面积
        for(int i = 0; i < row; ++i)
        {
            stack stk; // idx
            vector cur = heights[i];
            for(int j = 0; j < cur.size(); ++j)
            {
                if (stk.empty() || cur[j] >= cur[stk.top()]) 
                {
                    stk.push(j);
                } 
                else 
                {
                    int h = stk.top();
                    stk.pop();
                    res= max(res, cur[h] *(stk.empty() ? j : j - stk.top() - 1));
                    --j;  //!!! 下一次要在利用j和栈顶比较
                }
            }
            /*等同于下面
            while (idx < cur.size()) {
             if (stk.empty() || cur[idx] >= cur[stk.top()]) {
                 stk.push(idx++);
             } else {
                int h = stk.top();
                stk.pop();
                max_a = max(max_a, cur[h] *(stk.empty() ? idx : idx - stk.top() - 1));
             }
         }
            */
        }
        return res;
    }
};

 

 

 

 

 

84. Largest Rectangle in Histogram, Hard 在直方图上求最大矩形

方法1:利用栈, 栈维护一个高度是升序的idx, 当当前的height小于栈顶对应的高度时,计算矩阵面积;当当前的height大于栈顶对应的高度时,入栈。

 

class Solution {
public:
    // solution 1:
    /*
    int largestRectangleArea(vector& heights) {
        int res = 0;
        stack s; // save idx
        heights.push_back(0); //如果都是heights完全是升序的,那么就要最后计算面积
        for(int i = 0; i < heights.size(); ++i)
        {
            if(s.empty() || heights[s.top()] < heights[i])
            {
                s.push(i);
            }
            else
            {
                int idx = s.top();
                s.pop();
                res = max(res, heights[idx] * (s.empty() ? i : (i - s.top() - 1)));
                --i;
            }
        }
        return res;
    }*/
    
    //solution 2:
    int largestRectangleArea(vector& heights) {
        int res = 0;
        stack s; // save idx
        heights.push_back(0); //如果都是heights完全是升序的,那么就要最后计算面积
        for(int i = 0; i < heights.size(); ++i)
        {
            while(!s.empty() && heights[s.top()] > heights[i])
            {
                int idx = s.top();
                s.pop();
                res = max(res, heights[idx] * (s.empty() ? i : (i - s.top() - 1)));
            }

            s.push(i);
        }
        return res;
    }
};

10. 嵌套迭代器

341. Flatten Nested List Iterator

利用栈存放容器中的数据,倒序存放数据。

 


【leetcode Top Interview Questions】【stack】分类下面:  

easy 2道,medium 4道,hard 2道 (2019.09.09)

【easy】

155.Min Stack  最小栈,O(1)时间复杂度获取栈中最小值 
20.Valid Parentheses  判断括号是否匹配

【medium】

94. Binary Tree Inorder Traversal  中序遍历二叉树
341.Flatten Nested List Iterator 
103.Binary Tree Zigzag Level Order Traversal
150.Evaluate Reverse Polish Notation

【hard】

42.Trapping Rain Water 
84.Largest Rectangle in Histogram  

你可能感兴趣的:(leetcode)