[LeetCode]-3-stack & queue

LeetCode-3

In java, you can directly use LinkedList as the basic stack or queue: push() method is used to press the stack, and offer() method is used to put it at the end of the queue; The poll() method is used to exit the stack or pop up the queue header element. If there is no element at the top of the stack or the queue header, null will be returned (if there is no element with pop(), an exception will be thrown); The peek() method is used to obtain the stack top element or the queue header element. If not, null will be returned

Stack

232. Implement queue with stack

Implement a queue with two stacks. Two stacks, stack 1 and stack 2, are established. When data is input, it is input into stack 1. When data is to be taken out, all elements of stack 1 are taken out of the stack and pressed into stack 2. In this way, the original access sequence in stack 1 is i reversed. When data is taken out, it is taken from stack 2 to realize FIFO

class MyQueue {
    private LinkedList<Integer> stack1;
    private LinkedList<Integer> stack2;
    public MyQueue() {
        stack1 = new LinkedList<>();
        stack2 = new LinkedList<>();
    }
    //Join the team
    public void push(int x) {
        stack1.push(x);
    }
    //Out of the team
    public int pop() {
        if(stack2.peek() == null){
            if(stack1.peek() == null){
                return -1;
            }else{
                while (stack1.peek() != null){
                    stack2.push(stack1.poll());
                }
                return stack2.poll();
            }
        }else{
            return stack2.poll();
        }
    }
    //Get queue header element
    public int peek() {
        if(stack2.peek() == null){
            if(stack1.peek() == null){
                return -1;
            }else{
                while (stack1.peek() != null){
                    stack2.push(stack1.poll());
                }
                return stack2.peek();
            }
        }else{
            return stack2.peek();
        }
    }
    //Determine whether the queue is empty
    public boolean empty() {
        if(stack2.peek() == null){
            if(stack1.peek() == null){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
}

20. Valid brackets

Using the stack, when traversing the string, if you encounter the left bracket, you will enter the stack. If you encounter the right bracket, you will judge whether the element at the top of the stack is the corresponding left bracket. If so, let the left bracket out of the stack, otherwise let the right bracket into the stack. Therefore, when you encounter the right parenthesis, you should judge the top element of the stack. At this time, you should first pay attention to whether the stack is empty

public boolean isValid(String s) {
    LinkedList<Character> stack = new LinkedList<>();
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if(c == '(' || c == '{' || c == '['){
            stack.push(c);
        }else if(c == ')'){
            //When entering the right bracket, you will judge whether the top element of the stack is the corresponding left bracket, so you should first judge whether the stack is empty
            if(!stack.isEmpty() && stack.peek() == '('){
                stack.poll();
            }else {
                stack.push(c);
            }
        }else if(c == '}'){
            if(!stack.isEmpty() && stack.peek() == '{'){
                stack.poll();
            }else {
                stack.push(c);
            }
        }else if(c == ']'){
            if(!stack.isEmpty() && stack.peek() == '['){
                stack.poll();
            }else {
                stack.push(c);
            }
        }
    }
    return stack.isEmpty();
}

1047. Delete all adjacent duplicates in the string

Using the stack, determine whether each element is the same as the top element of the stack before entering the stack. If it is the same, take the top element out of the stack, otherwise put the traversed element into the stack

public String removeDuplicates(String s) {
    LinkedList<Character> stack = new LinkedList<>();
    for (int i = 0; i < s.length(); i++) {
        Character peek = stack.peek();
        char c = s.charAt(i);
        if(peek == null || peek != c){
            stack.push(c);
        }else {
            stack.poll();
        }
    }
    /*=====Transfer the characters in the stack to the character array, and then pass the array into the string constructor to construct the final answer
    int size = stack.size();
    if(size == 0){
        return "";
    }
    char[] chars = new char[size];
    for (int i = size - 1; i >= 0; i--) {
        chars[i] = stack.poll();
    }
    return new String(chars);*/
    //=========Use string splicing to initialize an empty ship, and connect the pop-up elements in the stack in front of the string in reverse order. It's much slower than the above
    String res = "";
    while (stack.peek() != null){
        res = stack.poll() + res;
    }
    return  res;
}

150. Evaluation of inverse Polish expression

Use the stack to store the numbers and symbols in the expression, and simulate the process according to the calculation method of the inverse Polish expression

public int evalRPN(String[] tokens) {
        LinkedList<String> stack = new LinkedList<>();
        for (String token : tokens) {
        	//If you encounter an operator, you can take out the two elements at the top of the stack for operation. According to the original expression, in subtraction and division,
        	//It should be the number that is put on the stack first as the subtraction or divisor, and the number that is put on the stack later as the subtracted and divisor
            if("+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token)){
                if(stack.size() >= 2){
                    int num1 = Integer.parseInt(stack.poll());
                    int num2 = Integer.parseInt(stack.poll());
                    switch (token){
                        case "+":{
                            stack.push(String.valueOf(num1 + num2));
                        }break;
                        case "-":{
                            stack.push(String.valueOf(num2 - num1));
                        }break;
                        case "*":{
                            stack.push(String.valueOf(num1 * num2));
                        }break;
                        default:{
                            stack.push(String.valueOf(num2 / num1));
                        }
                    }
                }else {
                    stack.push(token);
                }
            }else {
                stack.push(token);
            }
        }
        return Integer.parseInt(stack.poll());
    }

queue

225. Implement stack with queue

The stack is implemented with two queues. Establish two queues, queue 1 and queue 2. When inputting data into one of the queues, when taking out data, take out the elements of the queue with data one by one and enter another queue until the last element left in the queue with data is the top element of the whole stack. If you want to get out of the stack, just take the last element out of the queue directly; If you want to get the top element of the stack, you must first save the value of this element with an Integer variable, then add this element to another queue, and then return this value. Therefore, it can be seen that the two queues are empty when initializing the whole stack and popping all elements in the stack. At other times, only one queue in the two queues does not contain elements. It is necessary to judge before entering the stack, exiting the stack and obtaining the top element of the stack

class MyStack {
    private LinkedList<Integer> queue1;
    private LinkedList<Integer> queue2;
    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
	//Push 
    public void push(int x) {
        if(queue1.peek() == null){
            queue2.offer(x);
        }else {
            queue1.offer(x);
        }
    }
	//Out of stack
    public int pop() {
        if(queue1.peek() == null){
            if(queue2.peek() == null){
                return -1;
            }else {
                while (queue2.size() > 1){
                    queue1.offer(queue2.poll());
                }
                return queue2.poll();
            }
        }else {
            while (queue1.size() > 1){
                queue2.offer(queue1.poll());
            }
            return queue1.poll();
        }
    }
	//Get stack top element
    public int top() {
        if(queue1.peek() == null){
            if(queue2.peek() == null){
                return -1;
            }else {
                while (queue2.size() > 1){
                    queue1.offer(queue2.poll());
                }
                Integer value = queue2.peek();
                queue1.offer(queue2.poll());
                return  value;
            }
        }else {
            while (queue1.size() > 1){
                queue2.offer(queue1.poll());
            }
            Integer value = queue1.peek();
            queue2.offer(queue1.poll());
            return value;
        }
    }
	//Determine whether the stack is empty
    public boolean empty() {
        if(queue1.size() == 0 && queue2.size() == 0){
            return true;
        }
        return false;
    }
}

In fact, a queue can implement a stack. When obtaining the top element of the stack, all elements in the queue except the last element are out of the queue and re-enter the queue (that is, change to the end of the queue), so that the last element in the original queue can be changed to the head of the queue

239. Sliding window maximum (hard) - monotonic queue

Monotone queue is to specify that the elements in the queue must be monotonically increasing or decreasing based on the original queue. Only this requirement needs to be met. The specific operations and details of the monotone queue, such as the out of line or in line of elements, depend on the specific situation. In this problem, every time the window moves one bit, all the elements that may be the maximum value in the current sliding window are placed in the monotonic queue. When the new array elements caused by the move are not processed, we make the queue monotonically decrease, so that the queue header element is the largest element in the current queue, and then process the new elements, Take all the elements at the end of the queue that are smaller than the new element out of the queue, and then let the new element in the queue. In this way, the new queue is still in descending order. As mentioned earlier, what is put in the queue is the element that may be the maximum value in the current sliding window (the new element and its previous k-1 elements), and the maximum value must be the queue head element. Every time you move the window, a new element appears. Do this. However, to ensure that the current queue places elements that may be the maximum value of the current window, first ensure that all elements in the queue exist in the current window, so the queue in the code places the subscripts of elements in the array. When traversing the elements with subscript i, the subscripts of all elements in the queue must be [i - k + 1,i]

public int[] maxSlidingWindow(int[] nums, int k) {
    LinkedList<Integer> monotonousQueue = new LinkedList<>();
    //First, the first k elements are processed to initialize the monotone queue
    for (int i = 0; i < k; i++) {
        while (!monotonousQueue.isEmpty() && nums[monotonousQueue.peekLast()] < nums[i]){
            monotonousQueue.removeLast();
        }
        monotonousQueue.offer(i);
    }
    int[] res = new int[1 + nums.length - k];
    int index = -1;
    for(int i = k;i < nums.length;i++){
        res[++index] = nums[monotonousQueue.peek()];
        //Exclude elements that cannot exist in the current window
        while (!monotonousQueue.isEmpty() && monotonousQueue.peek() < i - k + 1){
            monotonousQueue.poll();
        }
        while (!monotonousQueue.isEmpty() && nums[monotonousQueue.peekLast()] < nums[i]){
            monotonousQueue.removeLast();
        }
        monotonousQueue.offer(i);
    }
    //After the last element in the loop is processed, the maximum value of its window is not put into the result array
    res[++index] = nums[monotonousQueue.peek()];
    return res;
}

Tags: Java Algorithm leetcode

Posted on Thu, 11 Nov 2021 16:27:00 -0500 by fangorn