leetcode essence of algorithm interview in Dachang 17. Stack

leetcode essence of algorithm interview in Dachang 17. Stack

Video Explanation (efficient learning): Click to learn

catalog:

1. Introduction

2. Time and space complexity

3. Dynamic planning

4. Greed

5. Binary search

6. Depth first & breadth first

7. Double pointer

8. Sliding window

9. Bit operation

10. Recursion & divide and conquer

11 Pruning & backtracking

12. Reactor

13. Monotone stack

14. Sorting algorithm

15. Linked list

16.set&map

17. Stack

18. Queue

19. Array

20. String

21. Trees

22. Dictionary tree

23. Consolidation

24. Other types of questions

  • Stack features: first in and last out (FILO)

  • Usage scenario: decimal to binary function call stack

  • js has no stack, but it can be simulated with an array

    42/2 42%2=0
    21/2 21%2=1
    10/2 10%2=0
    5/2   5%2=1
    2/2   2%2=0
    1/2   1%2=1
    stack: [0,1,0,1,0,1]
    res:    1 0 1 0 1 0
    
    fn1(){
      fn2()
    }
    fn2(){
        fn3()
      }
    fn3(){}
    fn1()
    
    stack:[fn1,fn2,fn3]
    
  • Time complexity of stack: input and output O(1), find O(n)

20. Valid brackets (easy)

Method 1. Stack

  • Idea: first, if the string can form valid parentheses, the length must be even. We can traverse the string. If we encounter the left parenthesis, we can temporarily store it. We expect that there will be a right parenthesis to match it. If we encounter the right parenthesis, we will check whether it can match the latest temporarily stored parentheses. This is consistent with the first in and last out characteristics of stack data structure. Therefore, we can prepare a stack to store bracket pairs. When traversing the string, if we encounter the left bracket into the stack, and if we encounter the right bracket, we can judge whether the right bracket can match the top element of the stack. At the end of the loop, we should also judge whether the stack is empty. If it is not empty, it is not a string matched by valid brackets
  • Complexity analysis: time complexity O(n), space complexity O(n), n is the length of the string

js:

var isValid = function(s) {
    const n = s.length;
    if (n % 2 === 1) {//If the string can form valid parentheses, the length must be even
        return false;
    }
    const pairs = new Map([//Stack bracket pairs
        [')', '('],
        [']', '['],
        ['}', '{']
    ]);
    const stk = [];
    for (let ch of s){//Circular string
        if (pairs.has(ch)) {
          	//If the right bracket is encountered, judge whether the right bracket can match the top element of the stack
            if (!stk.length || stk[stk.length - 1] !== pairs.get(ch)) {
                return false;
            }
            stk.pop();
        } else {
            stk.push(ch);//If the left bracket is encountered, it will be pushed into the stack
        }
    };
    return !stk.length;//At the end of the loop, it is also necessary to judge whether the stack is empty
};

Java:

class Solution {
    public boolean isValid(String s) {
        int n = s.length();
        if (n % 2 == 1) {
            return false;
        }

        Map<Character, Character> pairs = new HashMap<Character, Character>() {{
            put(')', '(');
            put(']', '[');
            put('}', '{');
        }};
        Deque<Character> stack = new LinkedList<Character>();
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            if (pairs.containsKey(ch)) {
                if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
                    return false;
                }
                stack.pop();
            } else {
                stack.push(ch);
            }
        }
        return stack.isEmpty();
    }
}

232. Implement queue with stack (easy)

Method 1. Stack

The animation is too large. Click to view it

  • Idea: This is a simulation problem. It does not involve specific algorithms. It examines the mastery of stacks and queues. Using stack to model queue behavior, if only one stack is used, it will not work. Therefore, two stacks are required, one input stack and one output stack. Here, pay attention to the relationship between input stack and output stack. When push ing data, just put the data into the input stack, but in pop, the operation is more complex. If the output stack is empty, import all the data into the stack (note that import all), and then pop up the data from the stack. If the output stack is not empty, directly pop up the data from the stack. Finally, if the stack entry and stack exit are empty, the simulated queue is empty.
  • Complexity analysis: push time complexity is O(1), pop time complexity is O(n), because when pop, the output stack is empty, all elements of the input stack are added to the output stack. Space complexity O(n), two stack spaces

js:

var MyQueue = function() {
  //Prepare two stacks
   this.stack1 = [];
   this.stack2 = [];
};

MyQueue.prototype.push = function(x) {//Add input stack when push ing
   this.stack1.push(x);
};

MyQueue.prototype.pop = function() {
   const size = this.stack2.length;
   if(size) {//Judge whether the output stack is empty when push ing
       return this.stack2.pop();//If it is not empty, the output stack is out of the stack
   }
   while(this.stack1.length) {//If the output stack is empty, all elements of the input stack are added to the output stack
       this.stack2.push(this.stack1.pop());
   }
   return this.stack2.pop();
};

MyQueue.prototype.peek = function() {
   const x = this.pop();//Check the element reuse pop method of the queue head, and then push the element into the output stack
   this.stack2.push(x);
   return x;
};

MyQueue.prototype.empty = function() {
   return !this.stack1.length && !this.stack2.length
};

Java:

class MyQueue {

    Stack<Integer> stack1;
    Stack<Integer> stack2;

    public MyQueue() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }
    
    public void push(int x) {
        stack1.push(x);
    }
    
    public int pop() {    
        dumpStack1();
        return stack2.pop();
    }
    
    public int peek() {
        dumpStack1();
        return stack2.peek();
    }
    
    public boolean empty() {
        return stack1.isEmpty() && stack2.isEmpty();
    }

    private void dumpStack1(){
        if (stack2.isEmpty()){
            while (!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
    }
}

155. Minimum stack (easy)

  • Idea: define two stacks stack and min_stack, stack normal push, min_stack will only push the smaller elements in the stack and the top of the stack. getMin returns min_stack top element. Top returns the stack top element.
  • Complexity: the time complexity of all operations is O(1)

js:

var MinStack = function () {
    this.stack = [];
    this.min_stack = [Infinity];
};

//Stack normal push, min_stack will only push the smaller elements that need to be pushed into the stack and at the top of the stack
MinStack.prototype.push = function (x) {
    this.stack.push(x);
    this.min_stack.push(Math.min(this.min_stack[this.min_stack.length - 1], x));
};

//stack normal pop, min_stack normal pop
MinStack.prototype.pop = function () {
    this.stack.pop();
    this.min_stack.pop();
};

//Return stack top element
MinStack.prototype.top = function () {
    return this.stack[this.stack.length - 1];
};

//Return min_stack top element
MinStack.prototype.getMin = function () {
    return this.min_stack[this.min_stack.length - 1];
};


java:

class MinStack {
  Deque<Integer> stack;
  Deque<Integer> minStack;

  public MinStack() {
      stack = new LinkedList<Integer>();
      minStack = new LinkedList<Integer>();
      minStack.push(Integer.MAX_VALUE);
  }
  
  public void push(int x) {
      stack.push(x);
      minStack.push(Math.min(minStack.peek(), x));
  }
  
  public void pop() {
      stack.pop();
      minStack.pop();
  }
  
  public int top() {
      return stack.peek();
  }
  
  public int getMin() {
      return minStack.peek();
  }
}

946. Verify stack sequence (medium)

The animation is too large. Click to view it

  • Idea: use the stack to simulate the process of putting the stack into the stack. When the element at the position pointed by the index in popped is consistent with the element at the top of the stack, get out of the stack and index + +, and finally judge whether the stack is empty
  • Complexity: time complexity O(n), elements in pushed are pushed into and out of the stack once, space complexity O(n), and the size of the stack

js:

const validateStackSequences = (pushed, popped) => {
    const stack = [];//Use the stack to simulate the process of putting the stack into the stack
    let index = 0;
    const len = pushed.length;
    for (let i = 0; i < len; i++) {
        stack.push(pushed[i]);
      	//When the element at the position pointed to by the index in popped is consistent with the element at the top of the stack, it is out of the stack and the index++
        while (popped[index] !== undefined && popped[index] === stack[stack.length - 1]) {
            stack.pop();
            index++;
        }
    }
    return !stack.length;//Finally, judge whether the stack is empty
};

java:

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        if(pushed == null){
            return true;
        }
        Stack<Integer> stack = new Stack<>();
        int index = 0;
        for(int i=0;i<pushed.length;i++){
            stack.push(pushed[i]);
            while(!stack.isEmpty() && index < popped.length && popped[index] == stack.peek()){
                int pop = stack.pop();
                index++;
            }
        }
        return stack.isEmpty();
    }
}



445. Adding two numbers II (medium)

  • Idea: push the nodes of the two linked lists into the stack, and then keep coming out of the stack, calculate the value and carry of each position, and connect them in series to form a new linked list
  • Complexity: time complexity O(max(m,n)), m, n is the length of two linked lists, and space complexity O(m+n)

js:

var addTwoNumbers = function(l1, l2) {
    const stack1 = [];
    const stack2 = [];
    while (l1 || l2) {//Stack two linked lists
        if (l1) {
            stack1.push(l1.val);
            l1 = l1.next;
        }
        if (l2) {
            stack2.push(l2.val);
            l2 = l2.next;
        }
    }
    let carry = 0;
    let ansList = null;
    while (stack1.length || stack2.length || carry !== 0) {//Keep coming out of the stack
        const s1 = stack1.length ? stack1.pop() : 0;
        const s2 = stack2.length ? stack2.pop() : 0;
        let val = s1 + s2 + carry;
        carry = parseInt(val / 10);//Calculate carry
        val = val % 10;//Calculates the value of the current node
        const curNode = new ListNode(val);
        curNode.next = ansList;//Insert a new node before the linked list
        ansList = curNode;//Reassign ansList
    }
    return ansList;
};

java:

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Deque<Integer> stack1 = new LinkedList<Integer>();
        Deque<Integer> stack2 = new LinkedList<Integer>();
        while (l1 != null) {
            stack1.push(l1.val);
            l1 = l1.next;
        }
        while (l2 != null) {
            stack2.push(l2.val);
            l2 = l2.next;
        }
        int carry = 0;
        ListNode ansList = null;
        while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
            int s1 = stack1.isEmpty() ? 0 : stack1.pop();
            int s2 = stack2.isEmpty() ? 0 : stack2.pop();
            int val = s1 + s2 + carry;
            carry = val / 10;
            val %= 10;
            ListNode curNode = new ListNode(val);
            curNode.next = ansList;
            ansList = curNode;
        }
        return ansList;
    }
}

682. Baseball game (easy)

  • Complexity: time complexity O(n), space complexity O(n)

js:

let calPoints = function(ops) {
    let res = [];
    for(let i = 0; i < ops.length; i++){
        switch(ops[i]){
            case "C":
                res.pop();
                break;
            case "D":
                res.push(+res[res.length - 1] * 2);
                break;
            case "+":
                res.push(+res[res.length - 1] + +res[res.length - 2]);
                break;
            default:
                res.push(+ops[i]);
        }
    }
    return res.reduce((i, j) => i + j);
};

java:

class Solution {
    public int calPoints(String[] ops) {
        Stack<Integer> stack = new Stack();

        for(String op : ops) {
            if (op.equals("+")) {
                int top = stack.pop();
                int newtop = top + stack.peek();
                stack.push(top);
                stack.push(newtop);
            } else if (op.equals("C")) {
                stack.pop();
            } else if (op.equals("D")) {
                stack.push(2 * stack.peek());
            } else {
                stack.push(Integer.valueOf(op));
            }
        }

        int ans = 0;
        for(int score : stack) ans += score;
        return ans;
    }
}

Tags: leetcode

Posted on Fri, 03 Dec 2021 01:45:17 -0500 by dub