Stack & Queue

Copyright © 直通硅谷

http://www.zhitongguigu.com

Stack & Queue

  • Two Different Data Structure
  • Stack: LIFO (Last in first out)
  • Queue: FIFO (First in first out)

Copyright © 直通硅谷

http://www.zhitongguigu.com

Stack: LIFO

1

2

3

4

5

LIFO: Last In First Out

Copyright © 直通硅谷

http://www.zhitongguigu.com

Tower of Hanoi

Queue: FIFO

1

2

3

4

5

FIFO: First In First Out

Copyright © 直通硅谷

http://www.zhitongguigu.com

Queue: FIFO

1

2

3

4

5

FIFO: First In First Out

Copyright © 直通硅谷

http://www.zhitongguigu.com

Stack

Stack<String> stack = new Stack<String>();
Stack<String> stack = new Stack<>();

Java

C++

stack <string> cards;

Copyright © 直通硅谷

http://www.zhitongguigu.com

Stack<String> stack = new Stack<String>();
Stack<String> stack = new Stack<>();

List<Map<Integer,Set<String>>> p = new ArrayList<Map<Integer,Set<String>>>();
List<Map<Integer,Set<String>>> p = new ArrayList<>();

// polymorphism
List<Map<Integer,Set<String>>> p = new ArrayList<>();
ArrayList<Map<Integer,Set<String>>> p = new ArrayList<>();

Java Diamond Operator

Copyright © 直通硅谷

http://www.zhitongguigu.com

Basic Operation

  • size
  • pop
  • push
  • peek
  • size
  • pop
  • push
  • top

Java

C++

Copyright © 直通硅谷

http://www.zhitongguigu.com

Stack

How to use Array to implement a stack?

Copyright © 直通硅谷

http://www.zhitongguigu.com

🤔

What might be the problems 

Array -> Stack

class Stack<T> {
  private int top;
  int capacity;
  T[] stack;
  public Stack(int inCapacity) {
    capacity = inCapacity;
    stack = (T[]) new Object[capacity];
    top = -1;
  }
  public int size() {
    return top + 1;
  }
  public void push(T value) {
    if(top + 1 == capacity) {
      throw new IllegalStateException("Stack is full");
    } else {
      stack[++ top] = value;
    }
  }
  public T peek() {
    if(top == -1) {
      throw new IllegalStateException("Stack is empty");
    }
    else return stack[top];
  }
  public T pop() {
    if(top == -1) {
      throw new IllegalStateException("Stack is empty");
    } 
    else return stack[top--];
  }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

🤔

Memory Leak

public T pop() {
  if(top == -1) {
    throw new IllegalStateException("Stack is empty");
  } 
  else return stack[top--];
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

class Stack<T> {
  private int top;
  int capacity;
  T[] stack;
  public Stack(int inCapacity) {
    capacity = inCapacity;
    stack = (T[]) new Object[capacity];
    top = -1;
  }
  public int size() {
    return top + 1;
  }
  public void push(T value) {
    if(top + 1 == capacity) {
      throw new IllegalStateException("Stack is full");
    } else {
      stack[++ top] = value;
    }
  }
  public T peek() {
    if(top == -1) {
      throw new IllegalStateException("Stack is empty");
    }
    else return stack[top];
  }
  public T pop() {
    if(top == -1) {
      throw new IllegalStateException("Stack is empty");
    } 
    else {
        T result = stack[top--];
        stack[top + 1] = null;
        return result;
    }
  }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

When to use Stack?

  • Invoke a function
  • Recursion  (This is a special case of the first)
  • DFS (Depth-first Search) (This is a special case of the second)

Copyright © 直通硅谷

http://www.zhitongguigu.com

Stack in Operating System

  • Stack and Heap
  • Stack is Faster
  • Heap can dynamically allocate space
  • Objects are all in heap
  • Functions are in stacks

Copyright © 直通硅谷

http://www.zhitongguigu.com

Copyright © 直通硅谷

http://www.zhitongguigu.com

static void method(int value) {
    int a = value;
    int[] arr = new int[3];
    method(a + 2);
}

public static void main(String[] args) {
    method(3);
}

🤔

Copyright © 直通硅谷

http://www.zhitongguigu.com

static void method(int value) {
    if (value > 5) {
        return;
    }
    int a = value;
    int[] arr = new int[3];
    method(a + 2);
}

public static void main(String[] args) {
    method(3);
}

Stack in Operating System

  • Stack and Heap
  • Stack is Faster
  • Heap can dynamically allocate space
  • Objects are all in heap
  • Functions are in stacks

Copyright © 直通硅谷

http://www.zhitongguigu.com

Stack in Operating System

Copyright © 直通硅谷

http://www.zhitongguigu.com

Queue

LinkedList<String> names = new LinkedList<>();

Java

C++

queue <string> names;

Copyright © 直通硅谷

http://www.zhitongguigu.com

Queue in Java is an Interface. Usually we use linkedlist to implement features for queues

Basic Operations

  • size
  • remove (poll)
  • add (offer)
  • element (peek)
  • size
  • pop_front
  • push_back

Java

C++

Copyright © 直通硅谷

http://www.zhitongguigu.com

Queue

How to use Array to implement a queue?

Copyright © 直通硅谷

http://www.zhitongguigu.com

What might be the problems 

🤔

Array => Queue

class Queue<T> {
    private int front;
    private int rear;
    int capacity;
    int size;
    T[] queue;
    public Queue(int inCapacity) {
        capacity = inCapacity;
        queue = (T[]) new Object[capacity];
        front = 0;
        rear = 0;
        size = 0;
    }
    public int size() {
        return size;
    }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

Array => Queue (Cont.d)

class Queue<T> {
    public void add(T value) {
        if (size == capacity) {
            throw new IllegalStateException("Queue is full");

        } else {
            queue[rear] = value;
            rear = (rear + 1) % capacity;
            size++;
        }
    }
    public T remove() {
        T value = null;
        if (size == 0) {
            throw new IllegalStateException("Cannot remove empty queue");
        } else {
            value = queue[front];
            front = (front + 1) % capacity;
            size--;
        }
        return value;
    }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

When to use Queue?

  • BFS (Breadth-first Search)
  • Priority Queue (Heap)
  • Multi Task Queue (Design)

Copyright © 直通硅谷

http://www.zhitongguigu.com

LinkedList Rule Them All

Copyright © 直通硅谷

http://www.zhitongguigu.com

Head

Tail

pop

(poll)

pollFirst

remove

removeFirst

push

addFirst

offerFirst

peek

(element)

getFirst

peekFirst

pollLast

removeLast

add

(offer)

addAll

addLast

offerLast

peekLast

getLast

java.util.LinkedList

Copyright © 直通硅谷

http://www.zhitongguigu.com

Practice 1

Implement Queue using Stacks

Use two Stacks to implement a queue

Copyright © 直通硅谷

http://www.zhitongguigu.com

Implement Queue using Stacks

Use two Stacks to implement a queue

 

Consider the basic operations of these two data structures

 

How to minimize the time complexity?

Copyright © 直通硅谷

http://www.zhitongguigu.com

Implement Queue using Stacks

Copyright © 直通硅谷

http://www.zhitongguigu.com

Implement Queue using Stacks

class MyQueue {
    LinkedList<Integer> stack = new LinkedList<>();
    // Push element x to the back of queue.
    public void push(int x) {
        LinkedList<Integer> temp = new LinkedList<>();
        while (!stack.isEmpty()) {
            temp.push(stack.pop());
        }
        stack.push(x);
        while (!temp.isEmpty()) {
            stack.push(temp.pop());
        }
    }
    // Removes the element from in front of queue.
    public void pop() {
        stack.pop();
    }
    // Get the front element.
    public int peek() {
        return stack.peek();
    }
    // Return whether the queue is empty.
    public boolean empty() {
        return stack.isEmpty();
    }
}

Big O

O(n)

Copyright © 直通硅谷

http://www.zhitongguigu.com

Implement Queue using Stacks

class MyQueue {
    Stack<Integer> temp = new Stack<Integer>();
    Stack<Integer> value = new Stack<Integer>();
    // Push element x to the back of queue.
    public void push(int x) {
        value.push(x);
    }
    // Removes the element from in front of queue.
    public void pop() {
        if(temp.isEmpty()) {
            while(!value.isEmpty()) {
                temp.push(value.pop());
            }
        }
        temp.pop();        
    }
    // Get the front element.
    public int peek() {
        if(temp.isEmpty()) {
            while(!value.isEmpty()) {
                temp.push(value.pop());
            }
        }
        return temp.peek();        
    }
    // Return whether the queue is empty.
    public boolean empty() {
        return temp.isEmpty() && value.isEmpty();       
    }
}

Big O

O(1)

Any Problem?

🤔

Copyright © 直通硅谷

http://www.zhitongguigu.com

Implement Queue using Stacks

class MyQueue {
    Stack<Integer> temp = new Stack<Integer>();
    Stack<Integer> value = new Stack<Integer>();
    // Push element x to the back of queue.
    public void push(int x) {
        value.push(x);
    }
    // Removes the element from in front of queue.
    public void pop() {
        reorder();
        temp.pop();        
    }
    // Get the front element.
    public int peek() {
        reorder();
        return temp.peek();        
    }
    // Return whether the queue is empty.
    public boolean empty() {
        return temp.isEmpty() && value.isEmpty();       
    }
    private void reorder() {
        if(temp.isEmpty()) {
            while(!value.isEmpty()) {
                temp.push(value.pop());
            }
        }
    }
}

Practice 2

a stack with max()

Instead normal stack operation, this stack will have a max() function that could return the current max value of the stack

Copyright © 直通硅谷

http://www.zhitongguigu.com

a stack with max()

Copyright © 直通硅谷

http://www.zhitongguigu.com

One stack cannot tell the max in O(1)

 

Need another stack to store the max

 

time <=> space

class MaxStack {
  Stack element;
  Stack maxValue;
  public MaxStack(int inCapacity) {
    element = new Stack(inCapacity);
    maxValue = new Stack(inCapacity);
  }
  public int size() {
    return element.size();
  }
  public void push(int value) {
    int currentMax;
    if(element.size() == 0) {
      currentMax = Integer.MIN_VALUE;
    } else {
      currentMax = maxValue.peek();
    }
    element.push(value);
    if(currentMax > value) {
      maxValue.push(currentMax);
    }
    else maxValue.push(value);
  }
  public int pop() {
    maxValue.pop();
    return element.pop();
  }
  public int getMax() {
    return maxValue.peek();
  }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

store < n extra

🤔

class MaxStack {
  Stack element;
  Stack maxValue;
  public MaxStack(int inCapacity) {
    element = new Stack(inCapacity);
    maxValue = new Stack(inCapacity);
  }
  public int size() {
    return element.size();
  }
  public void push(int value) {
    element.push(value);
    if(maxValue.isEmpty() || maxValue.peek() <= value) {
        maxValue.push(value);
    }
  }
  public int pop() {
    if (!maxValue.isEmpty() && maxValue.peek() == element.peek()) {
        maxValue.pop();
    }
    return element.pop();
  }
  public int getMax() {
    return maxValue.peek();
  }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

🤔

only use one stack

store < n extra

!maxValue.isEmpty()

class MaxStack {
    private class Element {
        int val;
        int max;
        public Element(int val, int max) {
            this.val = val;
            this.max = max;
        }
    }
    Stack<Element> stack = new Stack<>();
    public int size() {
        return stack.size();
    }
    public void push(int x) {
        int max = (stack.isEmpty()) ? x : Math.max(x, stack.peek().max);
        stack.push(new Element(x, max));
    }
    public int pop() {
        return stack.pop().val;
    }
    public int getMax() {
        return stack.peek().max;
    }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

Practice 3

Valid Parentheses

Copyright © 直通硅谷

http://www.zhitongguigu.com

Valid Parentheses

Copyright © 直通硅谷

http://www.zhitongguigu.com

We need to use the stack to store the information: Which left parentheses has not been matched yet.

 

Stack can help store every unused parentheses, no matter when the parentheses appears

public boolean isValid(String s) {
	Stack<Character> pair = new Stack<Character>();
	int n = s.length();
	if(n == 0) return true;
	for(int i = 0; i < n; i ++) {
		if(s.charAt(i) == '(' || s.charAt(i) == '[' || s.charAt(i) == '{')  {
			pair.push(s.charAt(i));
		}
		else if(s.charAt(i) == ')') {
			if(pair.isEmpty()) return false;
			if(pair.pop() != '(') return false;
		}
		else if(s.charAt(i) == ']') {
			if(pair.isEmpty()) return false;
			if(pair.pop() != '[') return false;
		}
		else if(s.charAt(i) == '}') {
			if(pair.isEmpty()) return false;
			if(pair.pop() != '{') return false;
		}
	}
	if(pair.isEmpty()) return true;
	return false;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

🤔

public boolean isValid(String s) {
	Stack<Character> pair = new Stack<Character>();
	int n = s.length();
	if(n == 0) return true;
	for(int i = 0; i < n; i ++) {
		if(s.charAt(i) == '(' || s.charAt(i) == '[' || s.charAt(i) == '{')  {
			pair.push(s.charAt(i));
		}
		else if(s.charAt(i) == ')') {
			if(pair.isEmpty() || pair.pop() != '(') return false;
		}
		else if(s.charAt(i) == ']') {
			if(pair.isEmpty() || pair.pop() != '[') return false;
		}
		else if(s.charAt(i) == '}') {
			if(pair.isEmpty() || pair.pop() != '{') return false;
		}
	}
	return pair.isEmpty();
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

🤔

messy?

public boolean isValid(String s) {
    LinkedList<Character> stack = new LinkedList<>();
    Map<Character, Character> hm = new HashMap<>();
    hm.put(')', '(');
    hm.put(']', '[');
    hm.put('}', '{');
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (hm.containsKey(c)) {
            if (stack.isEmpty() || !hm.get(c).equals(stack.pop())) {
                return false;
            }
        } else {
            stack.push(c);
        }
    }
    return stack.isEmpty();
}

Copyright © 直通硅谷

http://www.zhitongguigu.com

Practice 4

Bad Hair Day

Copyright © 直通硅谷

http://www.zhitongguigu.com

       
=       
=       =        Cows facing right -->
=     = =
=   = = =
= = = = = =
1 2 3 4 5 6  

Copyright © 直通硅谷

http://www.zhitongguigu.com

All the cows are facing right, and they can only see other cows in front of it and shorter than itself. It can be blocked by other taller cows.

Example: 6 2 3 1 7 4  Output: 5

Copyright © 直通硅谷

http://www.zhitongguigu.com

SUM(each cow can see how many other cows?) = SUM(each cow can be seen by how many other cows)

Copyright © 直通硅谷

http://www.zhitongguigu.com

SUM(each cow can see how many other cows?) = SUM(each cow can be seen by how many other cows)

How to use Stack?

How could Stack help record this?

Only allow cows whose height is lower than you into the stack

Copyright © 直通硅谷

http://www.zhitongguigu.com

How to use Stack?

Example: 6 2 3 1 7 4   Result: 5

Stack: 6

Stack: 6 2

Stack: 6 3

Stack: 6 3 1

Stack: 7

Stack: 7 4

Stack: 7

Stack: empty

Add 6

Add 2

Pop 2 Add 3

Add 1

Pop 6 3 1 Add 7

Add 4

Pop 4

Pop 7

 

 

+1

 

+3

 

+1

  public static int seeCows(int[] cow) {
    int length = cow.length;
    int totalNum = 0;
    Stack<Integer> cowStack = new Stack<Integer>();
    for(int i = 0; i < length; i ++){
      if(cowStack.size() == 0 || cowStack.peek() > cow[i]) {
        cowStack.push(cow[i]);
      }
      else {
        while(cowStack.size() > 0 && cowStack.peek() <= cow[i]) {
          cowStack.pop();
          totalNum += cowStack.size();
        }
        cowStack.push(cow[i]);
      }
    }
    while(cowStack.size() > 0) {
      cowStack.pop();
      totalNum += cowStack.size();
    }
    return totalNum;
  }

Copyright © 直通硅谷

http://www.zhitongguigu.com

=?

Big O?

O(n)

Monotonic Stack

单调栈

Copyright © 直通硅谷

http://www.zhitongguigu.com

Find an element's left/right larger/smaller element in O(n) time.

Practice 5

Largest Rectangle in Histogram

Copyright © 直通硅谷

http://www.zhitongguigu.com

Copyright © 直通硅谷

http://www.zhitongguigu.com

Copyright © 直通硅谷

http://www.zhitongguigu.com

Largest Rectangle in Histogram

Similar thought: How to use stack to find the right border?

Example: 2 1 5 6 2 3

Only put rectangle higher than peek into stack

The element before it is the left border

The element pushes it out is the right border

Monotonically increasing or decreasing?

Copyright © 直通硅谷

http://www.zhitongguigu.com

Largest Rectangle in Histogram

Example: 2 1 5 6 2 3

Stack: 2

Stack: 1

Stack: 1 5

Stack: 1 5 6

Stack: 1 2

Stack: 1 2 3

Stack: 1 2

Stack: 1

Stack: Empty

Add 2

Pop 2 Add 1

Add 5

Add 6

Pop 6 5 Add 2

Add 3

Pop 3

Pop 2

Pop 1

 

2*1

 

 

6*1, 5*2

 

3*1

2*4

1*6

Copyright © 直通硅谷

http://www.zhitongguigu.com

Largest Rectangle in Histogram

Example: 2 1 5 6 2 3

How do we know the width?

Instead of directly putting height into stack, we put the index. Anyway height can be accessed by the index easily. And using index, we can know the width

Copyright © 直通硅谷

http://www.zhitongguigu.com

Largest Rectangle in Histogram

0 1 2 3 4 5

2 1 5 6 2 3

Stack: 0

Stack: 1

Stack: 1 2

Stack: 1 2 3

Stack: 1 4

Stack: 1 4 5

Stack: 1 4

Stack: 1

Stack: empty

Add 0

Pop 0 Add 1

Add 2

Add 3

Pop 2 3 Add 4

Add 5

Pop 5

Pop 4

Pop 1

 

2*1

 

 

6*1, 5*2

 

3*1

2*4

1*6

Copyright © 直通硅谷

http://www.zhitongguigu.com

public int largestRectangleArea(int[] height) {
    int area = 0;
    jStack<Integer> stack = new Stack<Integer>();
    for (int i = 0; i < height.length; i++) {
        if (stack.empty() || height[stack.peek()] < height[i]) {
            stack.push(i);
        } else {
            int start = stack.pop();
            int width = stack.empty() ? i : i - stack.peek() - 1;
            area = Math.max(area, height[start] * width);
            i--;
        }
    }
    while (!stack.empty()) {
        int start = stack.pop();
        int width = stack.empty() ? height.length : height.length - stack.peek() - 1;
        area = Math.max(area, height[start] * width);
    }
    return area;
}  

🤔

Copyright © 直通硅谷

http://www.zhitongguigu.com

public int largestRectangleArea(int[] height) {
    int n = height.length;
    int result = 0;
    Stack<Integer> stack = new Stack<>();
    for (int i = 0; i <= n; i++) {
        int cur = (i == n) ? 0 : height[i];
        while (!stack.isEmpty() && cur < height[stack.peek()]) {
            int area = height[stack.pop()] * (stack.isEmpty() ? i : i - 1 - stack.peek());
            result = Math.max(area, result);
        }
        stack.push(i);
    }
    return result;
}  

cur <= height[stack.peek()]

Exist Balance Number

Copyright © 直通硅谷

http://www.zhitongguigu.com

Given an array of integers.

Is there a number k in this array that

k is larger than all the numbers before it and smaller than all the numbers after it?

[1,2,3,4,5] -> true

[6,2,3,8,10,9] -> true

[4,3,5,2] -> false

[2] -> true

extra practice

Return all balance numbers

Homework 6.1

Copyright © 直通硅谷

http://www.zhitongguigu.com

Homework 6.2

Copyright © 直通硅谷

http://www.zhitongguigu.com

Homework 6.3

Copyright © 直通硅谷

http://www.zhitongguigu.com

Explain

Homework 6 (optional)

Copyright © 直通硅谷

http://www.zhitongguigu.com

Explain

Homework 6 (more)

Copyright © 直通硅谷

http://www.zhitongguigu.com

[GoValley-201612] Stack & Queue

By govalley201612

[GoValley-201612] Stack & Queue

Week 2 Lec 4

  • 893