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
- Basic Calculator
- Evaluate Reverse Polish Notation
- Flatten Nested List Iterator
- 132 Pattern (optional)
- Q -> S; S -> Q; Array -> Q, S
- Implement Java LL with Node
- Front & Rear
- popFront, popRear
- pushFront, pushRear
- peekFront, peekRear
- isEmpty, size
- Front & Rear
[GoValley-201612] Stack & Queue
By govalley201612
[GoValley-201612] Stack & Queue
Week 2 Lec 4
- 893