Logic Data Structure
Queue
FIFO == First In First Out, e.g. waith in a line
Usages
BFS related problems, Tree printout by levels
Sliding Window problems(Deque)
Only use one Queue, O(n)push, O(1)pop
Two Queues, O(1)push, O(n)pop1 2 3 4 5 queue = collections.deque() queue.append(1 ) queue.appendleft(2 ) queue.pop() queue.popleft()
What is Stack?
LIFO == Last in First Out, e.g. like a box
All operation available: push(), pop(), top()
Iterative DFS
Discussion
When do we consider “stack” in our algorithm?
Answer : when we linear scan an array/a string from left to right, and we need to look back the top element!
Find the biggest Rectangle in Histogram
Reverse Polish notation, a (b + c) -> abc+
String repeatedly deduplication. cabba -> caa -> c
Design Data Structure Implement a Queue by using two stacks
Key Point : When we pop all the elements from stack1 to stack2, we do not need to pop all the elements to stack1 again! Just put them to stack2 waiting for pop() function!
Time : pop(),amortized O(1) ; push(),O(1)
Space : O(n)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class MyQueue (object) : def __init__ (self) : self.stack1 = [] self.stack2 = [] def push (self, x) : self.stack1.append(x) def pop (self) : if len(self.stack2) == 0 : while self.stack1: self.stack2.append(self.stack1.pop()) return self.stack2.pop() def peek (self) : if len(self.stack2) == 0 : while self.stack1: self.stack2.append(self.stack1.pop()) return self.stack2[-1 ] def empty (self) : return len(self.stack1) == 0 and len(self.stack2) == 0
Two Stack: original stack & min stack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class MinStack (object) : def __init__ (self) : self.stack = [] self.minstack = [] def push (self, x) : self.stack.append(x) cmin = min(x, self.minstack[-1 ]) if self.minstack else x self.minstack.append(cmin) def pop (self) : self.stack.pop() self.minstack.pop() def top (self) : return self.stack[-1 ] def getMin (self) : return self.minstack[-1 ]
Min Stack Follow Up
How to optimize the space usage of minstack? (Assume there are a lot of duplicates) Try to make the elements in stack2 a descending order and store an element in stack2 <value, size of the stack1 when elements add to stack2>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class MinStack : def __init__ (self) : self.stack = [] self.minStack = [] def push (self, x) : self.stack.append(x) if not self.minStack or x < self.minStack[-1 ][0 ]: self.minStack.append((x, len(self.stack))) def pop (self) : self.stack.pop() if len(self.stack) < self.minStack[-1 ][1 ]: self.minStack.pop() def top (self) : return self.stack[-1 ] def getMin (self) : return self.minStack[-1 ][0 ]
popMax() – Retrieve the maximum element in the stack, and remove it. If you find more than one maximum elements, only remove the top-most one.
TreeMap in Java!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class MaxStack (object) : def __init__ (self) : self.stack = [] def push (self, x) : self.stack.append((x, max(x, self.stack[-1 ][1 ] if self.stack else None ))) def pop (self) : return self.stack.pop()[0 ] def top (self) : return self.stack[-1 ][0 ] def peekMax (self) : return self.stack[-1 ][1 ] def popMax (self) : m = self.stack[-1 ][1 ] temp = [] while self.stack[-1 ][0 ] != m: temp.append(self.pop()) self.stack.pop() map(self.push, reversed(temp)) return m
TODO : Using Stack for Selection Sort; Implement Deque using stacks
1 2 3 4 5 6 7 8 9 10 11 12 class Solution (object) : def isValid (self, s) : stack = [] pdic = {'(' :')' , '{' :'}' , '[' :']' } for ch in s: if ch in "({[" : stack.append(pdic[ch]) else : if len(stack) == 0 or stack[-1 ] != ch: return False stack.pop() return len(stack) == 0
O(1) Stack Remove 3 or more duplicates repeatedly
Stack + traversal pointer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def removeDuplicates (s) : stack = [] i = 0 print(s) while i < len(s): if len(stack) > 1 and s[i] == stack[-1 ] == stack[-2 ]: while i < len(s) and s[i] == stack[-1 ]: i += 1 stack.pop() stack.pop() else : stack.append(s[i]) i += 1 return stack if __name__ == "__main__" : string = raw_input() res = removeDuplicates(string) print(res)
Use Two pointers to imitate the stack!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def removeDuplicates (s) : i = 0 slow = -1 while i < len(s): if slow > 0 and s[i] == s[slow] == s[slow-1 ]: while i < len(s) and s[i] == s[slow]: i += 1 slow -= 2 else : slow += 1 s[i], s[slow] = s[slow], s[i] i += 1 return s[:slow+1 ] if __name__ == "__main__" : string = raw_input() res = removeDuplicates(list(string)) print(res)
Stack, Space : O(m + n)
Two Pointers, Space : O(1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution (object) : def backspaceCompare (self, S, T) : p1, p2 = len(S)-1 , len(T)-1 while p1 >= 0 or p2 >= 0 : back1 = 0 while (p1 >= 0 and S[p1] == '#' ) or back1 > 0 : back1 += 1 if S[p1] == '#' else -1 p1 -= 1 back2 = 0 while (p2 >= 0 and T[p2] == '#' ) or back2 > 0 : back2 += 1 if T[p2] == '#' else -1 p2 -= 1 if p1 < 0 and p2 < 0 : return True elif p1 < 0 or p2 < 0 : return False else : if S[p1] != T[p2]: return False else : p1 -= 1 p2 -= 1 return p1 == p2