美文网首页
Stack and Queue

Stack and Queue

作者: 猛男向前冲冲冲 | 来源:发表于2018-09-19 23:59 被阅读0次

    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;
        }
    }
    

    相关文章

      网友评论

          本文标题:Stack and Queue

          本文链接:https://www.haomeiwen.com/subject/vurbnftx.html