數據結構
最小棧
設計一個棧結構,支持 push, pop, top操作,並能以恆定的時間獲取棧中元素的最小值.
- push(x) – Push element x onto stack.
- pop() – Removes the element on top of the stack.
- top() – Get the top element.
- getMin() – Retrieve the minimum element in the stack.
# Ruby
class MinStack
def initialize
@mins, @stack = [], []
end
def push(x)
@stack.push x
@mins.push x if @mins.empty? or x <= @mins.last
end
def pop
@mins.pop if @stack.pop == @mins.last
end
def top
@stack.last
end
def get_min
@mins.last
end
end
使用2個棧,一個棧stack裝元素,另一個棧mins裝最小值。每出現一個新的最小值,就將之壓入mins棧中,當pop stack時,彈出的元素恰好也等於mins的棧頂,那麼也pop mins, 保持mins的棧頂始終是stack中元素的最小值。
爲什麼def push(x) 中 x <= @mins.last要取等號,是因爲stack中可能有幾個相等的最小值。
Min Stack
用棧實現隊列
- 只能使用標準的棧操作:push to top, peek/pop from top, size, is empty
- 假設對該隊列的操作都是有效的,即不會對空隊列pop/peek
class Queue
# Initialize your data structure here.
def initialize
@stack, @temp = [], []
end
# @param {Integer} x
# @return {void}
def push(x)
if @temp.any? then @stack.push @temp.pop until @temp.empty? end
@stack.push x
end
# @return {void}
def pop
if @temp.empty? then @temp.push @stack.pop until @stack.empty? end
@temp.pop
end
# @return {Integer}
def peek
if @temp.empty? then @temp.push @stack.pop until @stack.empty? end
@temp.last
end
# @return {Boolean}
def empty
@stack.empty? and @temp.empty?
end
end
基本想法是Queue類的實例持有2個實例變量,分別爲stack和temp, 均爲array,當做棧來用。僅對stack做push操作,當需要做pop/peek操作時,把棧stack中的元素移入棧temp, 那麼temp的top即隊列的top,對temp做pop/peek操作。
Implement Queue using Stacks
用隊列實現棧
跟上題基本倒過來,不過是把對數組的操作push, pop換成了unshift和shift.
class Stack
# Initialize your data structure here.
def initialize
@q1, @q2 = [], []
end
# @param {Integer} x
# @return {void}
def push(x)
if @q2.any? then @q1.unshift @q2.pop until @q2.empty? end
@q1.push x
end
# @return {void}
def pop
if @q2.empty? then @q2.unshift @q1.shift until @q1.empty? end
@q2.shift
end
# @return {Integer}
def top
if @q2.empty? then @q2.unshift @q1.shift until @q1.empty? end
@q2.first
end
# @return {Boolean}
def empty
@q1.empty? and @q2.empty?
end
end