Stack and Queue

LC155. Min Stack
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> Returns -3.
minStack.pop();
minStack.top(); --> Returns 0.
minStack.getMin(); --> Returns -2.

class MinStack {
    //思想就是建两个栈,一个是正常的操作,另一个是存放实时的最小值
    private Stack<Integer> stack;
    private Stack<Integer> minStack;

    /** initialize your data structure here. */
    public MinStack() {
        stack = new Stack<Integer>();
        minStack = new Stack<Integer>();
    }
    
    public void push(int x) {
        stack.push(x);
        if(minStack.isEmpty()){
            minStack.push(x);
        } else {
            minStack.push(Math.min(x, minStack.peek()));
        }
    }
    
    public void pop() {
        stack.pop();
        minStack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

LC232. Implement Queue using Stacks

class MyQueue {
    private Stack<Integer> stack1; 
    private Stack<Integer> stack2;
    /** Initialize your data structure here. */
    public MyQueue() {
        stack1 = new Stack<Integer>();
        stack2 = new Stack<Integer>();
    }
    private void stack2ToStack1(Stack stack1, Stack stack2){
        while(!stack2.isEmpty()){
            stack1.push(stack2.pop());//第二个栈先判断第一个栈是不是非空,再把元素一一添加进第二个栈
        }
    }
    /** Push element x to the back of queue. */
    public void push(int x) {
         stack2.push(x);//第一个栈正常放入数
    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        this.stack2ToStack1(stack1, stack2);
        return stack1.pop();
    }
    
    /** Get the front element. */
    public int peek() {
         this.stack2ToStack1(stack1, stack2);
        return stack1.peek();
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
        this.stack2ToStack1(stack1, stack2);
        return stack1.isEmpty();
    }
}

LC84. Largest Rectangle in Histogram
Input: [2,1,5,6,2,3]
Output: 10

 public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) return 0;
        
        Stack<Integer> stack = new Stack<Integer>();
        int max = 0;
        for (int i = 0; i <= heights.length; i++){
            int cur = (i == heights.length) ? -1 : heights[i];//在最后的末位补上-1,能让单调栈中的所有元素都能pop出来。
            while(!stack.isEmpty() && cur <= heights[stack.peek()]){//当有元素小于栈顶的元素时,需要把栈顶的元素pop掉,此时恰巧可以计算以pop掉的元素为最小高度的最大面积
                int height = heights[stack.pop()];//此时已经pop掉了栈顶元素所以后续有可能是空的。
                int width = stack.isEmpty() ? i : i-stack.peek()-1;//如果是空的说明pop掉的元素的右边没有元素了,宽度就是i
                max = Math.max(max, height*width);
            }
            stack.push(i);
        }
        return max;
    }

LC42. Trapping Rain Water

public int trap(int[] height) {
        Stack<Integer> stack = new Stack<>();
        int sum = 0;
        int i = 0, j = height.length;
        while(i < j){
            if (stack.isEmpty() || height[i] <= height[stack.peek()]){//这句话是保证潜在bottom永远比栈顶元素小才有可能形成坑
                stack.push(i++);
            } else {//代表后面的元素比目前的栈顶元素大,这样bottom比两边都小所以形成了坑
                int bottom = stack.pop();
                if(stack.isEmpty()) continue; //如果bottom 后面没有栈元素了,那形成不了坑 
                sum += (Math.min(height[i], height[stack.peek()]) - height[bottom]) * (i - stack.peek() - 1);// 坑的左右两面的高度的最小值减去bottom然后乘以两面高度的的坐标的差减一。
            }
        }
        return sum;
    }

LC225. Implement Stack using Queues

class MyStack {
    Queue<Integer> q1;
    Queue<Integer> q2;
    /** Initialize your data structure here. */
    public MyStack() {
        q1 = new LinkedList<Integer>();
        q2 = new LinkedList<Integer>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        if (!q1.isEmpty()){
            q1.add(x);
        } else {
            q2.add(x);
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        int x = 0;
        if (q2.isEmpty()){
            while (!q1.isEmpty()){
                x = q1.remove();
                if(!q1.isEmpty()){
                    q2.add(x);
                }
            }
        } else if (q1.isEmpty()){
            while (!q2.isEmpty()){
                x = q2.remove();
                if (!q2.isEmpty()){
                    q1.add(x);
                }
            }
        }
        return x;
    }
    
    /** Get the top element. */
    public int top() {
        int x = 0;
        if (q2.isEmpty()){
            while (!q1.isEmpty()){
                x = q1.remove();
                    q2.add(x);
            }
        } else if (q1.isEmpty()){
            while (!q2.isEmpty()){
                x = q2.remove();
                   q1.add(x);
            }
        }
        return x;
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        if (q1.isEmpty() && q2.isEmpty()) return true;
        else return false;
    }
}

LC71. Simplify Path
···
public String simplifyPath(String path) {
Stack<String> stack = new Stack<>();

    String[] str = path.split("/");// 把字符串分割成只含有"","..","."和文件路径的字符串数组
    for(String s : str){
        if(s.equals("..")){
            if(!stack.isEmpty())
                stack.pop(); //如果他的前置文件路径是遇到..,他的前置文件路径就要被pop掉
        } else if (!s.equals(".") && !s.equals("")){
            stack.push(s);//遇到没有"","."的说明是正常路径
        }
    }
    
    String res = "";
    while(!stack.isEmpty()){
        res = "/" + stack.pop() + res;
    }
    if (res.length() == 0) return "/";
    return res;
}

···
LC150. Evaluate Reverse Polish Notation
Input: ["2", "1", "+", "3", "*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9

public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for (String token : tokens){
            if (token.equals("+")){
                stack.push(stack.pop() + stack.pop());
            } else if (token.equals("-")){
                int b = stack.pop();
                int a = stack.pop();
                stack.push(a - b);
            } else if (token.equals("*")){
                stack.push(stack.pop() * stack.pop());
            } else if (token.equals("/")){
                int b = stack.pop();
                int a = stack.pop();
                stack.push(a / b);
            } else {
                stack.push(Integer.parseInt(token));
            }
        }
        return stack.pop();
    }

LC20. Valid Parentheses
Input: "{[]}"
Output: true;

 public boolean isValid(String s) {
        char[] strs =s.toCharArray();
        Stack<Character> stack = new Stack<>();
        for (Character str : strs){
            if(str == '('){
                stack.push(')');
            } else if (str == '['){
                stack.push(']');
            } else if (str == '{'){
                stack.push('}');//遇到一个左括号,就把右括号放进栈里,根据栈的特性,当遇到不是左括号时,栈顶的元素一定时最后一个左括号对应的右括号
            } else {
                if (stack.isEmpty() || stack.pop() != str){
                    return false;//如果未遍历完栈空了,或者pop出的不是元素则是false
                }
            }
        }
        return stack.isEmpty(); //最后根据对称性,栈应该是空的
    }
  1. Basic Calculator II
 // String/stack
    //3+5-4/6, 先在第一个数前加+,因为不可能是负数,所以sign是+
    //步骤是 3 +? -> +3,0, 5 +? -> +5, 0
    public int calculate(String s) {
       if (s == null || s.length() == 0) return 0;
       Stack<Integer> stack = new Stack<>();
        char sign = '+';
        int num = 0;
        
        for (int i = 0; i < s.length(); i++){
            char c =s.charAt(i);
            if (Character.isDigit(c)){
            num = num*10 + c -'0';
            }// 累加数字
            if (c!=' ' && !Character.isDigit(c) || i + 1 == s.length()){
                if (sign == '+'){
                    stack.push(num);
                } else if (sign == '-'){
                    stack.push(-num);
                } else if (sign == '/'){
                    stack.push(stack.pop() / num);
                } else if (sign == '*'){
                    stack.push(stack.pop() * num);
                }
                sign = c;
                num = 0;
            }
        }
        int res = 0;
        while(!stack.isEmpty()){
            res += stack.pop();
        }
        return res;
    }

LC224. Basic Caculator

class Solution {
    // 3 + (5 + 4)
    public int calculate(String s) {
        int res = 0, num = 0, sign = 1;
        
        Stack<Integer> stack = new Stack<>();
        char[] chars = s.toCharArray();
        
        for (Character c : chars){
            if(Character.isDigit(c))
                num = num*10 + c - '0';
            if(c == '+' || c == '-'){
                res += sign * num;//计算的是前一次的数
                sign = (c == '+') ? 1 : -1;
                num = 0;
            } else if (c == '('){
                stack.push(res); 
                stack.push(sign); // 记录括号前的总和和符号
                res = 0;
                sign = 1; //初始化和和符号
            } else if (c == ')'){
                res += sign * num;
                num = 0;
                res *= stack.pop();
                res += stack.pop();//计算完括号里的9,再把括号外的和加上,第一个stack.pop是括号外的符号
            }
        }
        res += sign*num;
        return res;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容