Java reviews common data structures and stacks and queues of common interview questions

Keywords: Java data structure queue stack

Tip: please learn the knowledge points of linked list before reading

Java reviews common data structures and arrays and linked lists of common interview questions

Stack and queue

  1. Stack - First In First Out (FIFO)
    • Array or Linked List
  2. Queue - First In Last Out (FILO)
    • Array or Linked List

Stack

Structural features of first in and last out

Common methods of stack

boolean empty() -- returns true if the stack is empty, and false if the stack contains elements.
Object peek() -- returns the element at the top of the stack, but does not delete it in the stack.
Object pop() -- returns the element at the top of the stack and deletes it in the process.
Object push (Object element) -- push the element onto the stack and return the element at the same time.
int search(Object element) -- search for element in the stack. If it is found, it returns its relative to the top of the stack
The offset of the. Otherwise, - 1 is returned.

Stack with linked list

package com.gdpu.Stack;

import LinkedList.ListNode;

import java.util.Iterator;

/**
 * Stack with linked list
 * The header node does not put data
 * head The first node pointed to by is the top of the stack
 */
public class Stack<T> implements Iterable{

    //Record first node
    private ListNode head;
    //Number of elements in the stack
    private int N;

    public Stack() {
        this.head = new ListNode(null,null);
        this.N=0;
    }

    //Judge whether the number of elements in the current stack is 0
    public boolean isEmpty(){
        return N==0;
    }

    //Gets the number of elements in the stack
    public int size(){
        return N;
    }

    //Stack the t element
    public void push(T t){
        //Find the first node pointed to by the first node
        ListNode oldFirst = head.next;
        //Create a new node
        ListNode newNode = new ListNode(t, null);
        //Let the first node point to the new node
        head.next = newNode;
        //Let the new node point to the original first node
        newNode.next=oldFirst;
        //Number of elements + 1;
        N++;
    }
    
    //Pop up stack top element
    //Returns the element at the top of the stack and deletes it in the process
    public T pop(){
        //Find the first node pointed to by the first node
        ListNode oldFirst = head.next;
        if (oldFirst==null){
            return null;
        }
        //Let the first node point to the next node of the original first node
        head.next=oldFirst.next;
        //Number of elements - 1;
        N--;
        return (T) oldFirst.val;
    }
    
    //Returns the element at the top of the stack, but does not delete it from the stack.
    public T peek(){
        //Find the first node pointed to by the first node
        ListNode oldFirst = head.next;
        if (oldFirst==null){
            return null;
        }
        return (T) oldFirst.val;
    }


    @Override
    public Iterator<T> iterator() {
        return new SIterator();
    }

    private class SIterator implements Iterator{
        private ListNode n;

        public SIterator(){
            this.n=head;
        }

        @Override
        public boolean hasNext() {
            return n.next!=null;
        }

        @Override
        public Object next() {
            n = n.next;
            return n.val;
        }
    }
}

Queue

Basic concepts

Queue: it is called queue for short. It is a linear table with limited operation. It only allows insertion at one end of the table and deletion at the other end of the table. Inserting elements into the queue is called queue in or queue in; deleting elements is called queue out or queue out. Its operation feature is First In First Out (FIFO), and it only allows entry at the end of the queue and exit at the head of the queue.

Front: the end that can be deleted, also known as the head of the team

Rear: the end that allows insertion

Empty queue: an empty table that does not contain any elements

Basic operations of jdk's own queue

methodeffect
add()Join the queue (throw an IllegalStateException if it fails)
offer()Insert the specified element into the queue, and return true if successful; otherwise, return false
element()Get the value of the queue header, but not out of the queue (throw an exception NoSuchElementException if the queue is empty)
peek()Get the value of the queue head, but not out of the queue (null if the queue is empty)
poll()Get and remove the queue header (null if the queue is empty)
removeGet and remove the queue header (throw NoSuchElementException if the queue is empty)

Implement LinkQueue with single linked list

package Queue;

import LinkedList.ListNode;

import java.util.Iterator;

/**
 * Queue implemented with linked list
 * @param <T>
 */
public class LinkQueue<T> implements Iterable<T> {
    // Team leader
    private ListNode front;
    // Team tail
    private ListNode rear;
    // Number of elements
    private int size;

    /**
     * Create queue
     */
    public LinkQueue() {
        rear = front = null;
        size=0;
    }

    /**
     * Queue
     *
     * @param data
     */
    public void enQueue(T data) {
        ListNode<T> node = new ListNode<T>(data);
        //If it is an empty queue
        if (isEmpty()) {
            front = rear = node;
        } else {
            //Insert at tail
            rear.next = node;
            rear = node;
        }
        size++;
    }


    /**
     * Out of queue
     * @return Return data
     */
    public T deQueue() {
        if (isEmpty()) {
            throw new RuntimeException("Queue is empty");
        }
        ListNode<T> delete = front;
        //Change header node
        front = delete.next;
        delete.next=null; // help GC
        //Quantity minus 1
        size--;

        if (size == 0) {
            // When the last element is deleted, the front value is already null, but the real still points to the node. You need to set the real to null
            // The front and rear references of the last node do not point to it to help the GC process the node object
            rear = front;
        }

        return (T) delete.val;
    }

    /**
     * Determine whether the queue is empty
     */
    public boolean isEmpty() {
        return front == null && rear == null;
    }

    /**
     * Gets the number of elements in the queue
     */
    public int size() {
        return this.size;
    }

    //Add traversal module yourself
    @Override
    public Iterator<T> iterator() {
        return new QIterator();
    }

    private class QIterator implements Iterator{
        private ListNode n;

        public QIterator(){
            this.n=front;
        }
        @Override
        public boolean hasNext() {
            return n.next!=null;
        }

        @Override
        public Object next() {
            n = n.next;
            return n.val;
        }
    }
}

Practical topic

  1. 844. Compare strings with backspace
  2. 232. Implement queue with stack
  3. 225. Implement stack with queue
  4. 20. Valid brackets
  5. 150. Inverse Polish expression evaluation problem

Train of thought solution

844. Compare strings with backspace

  • Brute force traversal and translate the final string according to the rules
package com.gdpu.day1;

public class NO_844_backspaceCompare {

    public boolean backspaceCompare(String S, String T) {
        return transfer(S).equals(transfer(T));
    }
    /**
     * Violent traversal
     * Translate the last string according to the rule
     */
    public String transfer(String str){
        StringBuffer ret = new StringBuffer();
        for (int i =0;i<str.length();i++){
            char ch = str.charAt(i);
            if (ch!='#'){
                ret.append(ch);
            }else {
                if (ret.length()>0){
                    ret.deleteCharAt(ret.length()-1);
                }
            }
        }
        return ret.toString();
    }
}

  • Double pointers traverse S and T in reverse order respectively
/**
     * Two pointers traverse two strings in reverse
     */
    public boolean doublePointCompare(String S, String T) {
        int i = S.length() - 1;
        int j = T.length() - 1;
        int skipS = 0, skipT = 0;
        while (i > 0 || j > 0) {
            while (i >= 0) {
                if (S.charAt(i) == '#') {
                    skipS++;
                } else if (skipS > 0) {
                    skipS--;
                    i--;
                } else {
                    //Find one that can't be eliminated. Jump out
                    break;
                }
            }
            while (j >= 0) {
                if (T.charAt(j) == '#') {
                    skipT++;
                } else if (skipT > 0) {
                    skipS--;
                    j--;
                } else {
                    //Find one that can't be eliminated. Jump out
                    break;
                }
            }
            //If the index of both steps is greater than or equal to 0
            if (i >= 0 && j >= 0) {
                //If the two sides cannot eliminate the inequality at this time
                if (S.charAt(i) != T.charAt(j)) {
                    return false;
                }
            } else {
                //Excluding that all are greater than or equal to 0, if one is greater than or equal to 0
                if (i >= 0 || j >= 0) {
                    return false;
                }
            }
            i--;
            j--;
        }
        return true;
    }

20. Valid brackets

  • Using the mechanism of auxiliary stack
class Solution {
    public boolean isValid(String s) {
        int n = s.length();
        //If it is an odd number, it must not match completely
        if (n % 2 == 1) {
            return false;
        }
        //Define a map
        Map<Character, Character> pairs = new HashMap<Character, Character>() {{
            put(')', '(');
            put(']', '[');
            put('}', '{');
        }};
        Stack<Character> stack = new Stack<Character>();
        for (int i = 0;i<n;i++){
            char ch = s.charAt(i);
            //If it is a closing bracket
            if (pairs.containsKey(ch)){
                //At this time, if the stack is empty or the top elements of the stack do not match, false is returned
                if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
                    return false;
                }
                //Pop up stack top element after matching
                stack.pop();
            }
            //If there is no corresponding value, put it on the stack
            else {
                stack.push(ch);
            }
        }
        return stack.isEmpty();

    }
}

150. Inverse Polish expression evaluation problem

class Solution {
       public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0;i<tokens.length;i++){
            //If it is a number, put it on the stack
            if (isNumber(tokens[i])){
                stack.push(Integer.parseInt(tokens[i]));
            }else {
                int num1 = stack.pop();
                int num2 = stack.pop();
                switch (tokens[i]){
                    case "+": stack.push(num2+num1);break;
                    case "-": stack.push(num2-num1);break;
                    case "*": stack.push(num2*num1);break;
                    case "/": stack.push(num2/num1);break;
                    default:
                }
            }
        }
        return stack.peek();
    }

    public boolean isNumber(String token) {
        return !(token.equals("*"))&&!(token.equals("+"))&&!(token.equals("-"))&&!(token.equals("/"));
    }
}

232. Implement queue with stack

class MyQueue {
    //Input stack
    private Stack<Integer> inStack;
    //Output stack
    private Stack<Integer> outStack;  

    /** Initialize your data structure here. */
    public MyQueue() {
    
    this.inStack=new Stack<Integer>();
    this.outStack=new Stack<Integer>();

    }
    
    //Push 
    public void push(int x) {
        inStack.push(x);
    }

    //Out of stack
    public int pop() {
        //If the output stack is empty, pop up all the input stacks and press them into the output stack, and then outStack.pop()
        if(outStack.isEmpty()){
            while(!inStack.isEmpty()){
                outStack.push(inStack.pop());
            }
        }
        return outStack.pop();
    }

    //Get team head data
    public int peek() {
        if(outStack.isEmpty()){
            while(!inStack.isEmpty()){
                outStack.push(inStack.pop());
            }
        }
        return outStack.peek();
    }

    public boolean empty() {
        return inStack.isEmpty() && outStack.isEmpty();
    }
}

225. Implement stack with queue

-Use two queues

class MyStack {
   Queue<Integer> queue1;
   Queue<Integer> queue2;

   /** Initialize your data structure here. */
   public MyStack() {
       queue1 = new LinkedList<Integer>();
       queue2 = new LinkedList<Integer>();
   }
   //Push 
   public void push(int x) {
       //Current new element backward queue
       queue1.offer(x);
       //The old queue is backward
       while (!queue2.isEmpty()){
           queue1.offer(queue2.poll());
       }

       //Update the old queue after completion
       //In fact, queue1 at this time is already an empty queue
       Queue<Integer> tmp = queue1;
       queue1 = queue2;
       queue2 = tmp;
   }

   //Out of stack
   public int pop() {
       return queue2.poll();
   }

   public int top() {
       return queue2.peek();
   }

   public boolean empty() {
       return queue2.isEmpty();
   }

}

-Use 1 queue

class MyStack {
    Queue<Integer> queue;

    /** Initialize your data structure here. */
    public MyStack() {
        queue = new LinkedList<Integer>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        int n = queue.size();
        queue.offer(x);
        for (int i = 0; i < n; i++) {
            queue.offer(queue.poll());
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return queue.poll();
    }
    
    /** Get the top element. */
    public int top() {
        return queue.peek();
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue.isEmpty();
    }
}

summary

Through the above problems, repeatedly solve a variety of solutions, and basically master the stack and queue

Posted by jds580s on Fri, 08 Oct 2021 11:48:51 -0700