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
- Stack - First In First Out (FIFO)
• Array or Linked List - 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
method | effect |
---|---|
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) |
remove | Get 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
- 844. Compare strings with backspace
- 232. Implement queue with stack
- 225. Implement stack with queue
- 20. Valid brackets
- 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