题目描述(难度:中等)
翻转(也叫颠倒)栈的所有元素,例如输入栈{1, 2, 3, 4, 5},其中,1 处在栈顶,翻转之后的栈为{5, 4, 3, 2, 1},其中,5 处在栈顶。(来源:阿里)
方法一:借助队列
class Stack:
# 模拟栈
def __init__(self):
self.items = []
# 判断栈是否为空
def empty(self):
return len(self.items) == 0
# 返回栈的大小
def size(self):
return len(self.items)
# 返回栈顶元素
def top(self):
if not self.empty():
return self.items[len(self.items)-1]
else:
return None
# 弹栈
def pop(self):
if len(self.items) > 0:
return self.items.pop()
else:
print("栈已经为空")
return None
# 压栈
def push(self, item):
self.items.append(item)
class Queue:
def __init__(self):
self.arr = []
self.front = 0 # 队列头
self.rear = 0 # 队列尾
# 判断队列是否为空
def isEmpty(self):
return self.front == self.rear
# 返回队列的大小
def size(self):
return self.rear-self.front
# 返回队列首元素
def getFront(self):
if self.isEmpty():
return None
return self.arr[self.front]
# 返回队列尾元素
def getRear(self):
if self.isEmpty():
return None
return self.arr[self.rear-1]
# 删除队列头元素
def deQueue(self):
if self.rear > self.front:
# print("元素"+str(self.arr[self.front])+"出队成功")
self.front += 1
else:
print("队列已经为空,出队失败")
# 把新元素加入队列尾
def enQueue(self, item):
self.arr.append(item)
self.rear += 1
# 借助队列
def StackToQueue(s,q):
if s.empty():
return
top = s.top()
s.pop()
q.enQueue(top)
# 递归将栈顶元素入队
StackToQueue(s,q)
# 翻转栈
def reverse_stack(s,q):
if q.isEmpty():
return
Qtop = q.getFront()
q.deQueue()
s.push(Qtop)
reverse_stack(s,q)
if __name__ == "__main__":
s = Stack()
q = Queue()
s.push(5)
s.push(4)
s.push(3)
s.push(2)
s.push(1)
StackToQueue(s,q)
reverse_stack(s,q)
print("翻转后出栈顺序为:", end='')
while not s.empty():
print(s.top(), '', end='')
s.pop()
复杂度分析
- 时间复杂度都为 O ( n 2 ) O(n^2) O(n2)
- 空间复杂度为 O ( n ) O(n) O(n)
方法二:直接递归
由于水平有限,个人认为,递归的方法,在数理逻辑上比较易理解,但在计算机逻辑上不易理解,故暂时不做理解分析,待想到更好的方式去解析时,再详细解析。
class Stack:
# 模拟栈
def __init__(self):
self.items = []
# 判断栈是否为空
def empty(self):
return len(self.items) == 0
# 返回栈的大小
def size(self):
return len(self.items)
# 返回栈顶元素
def top(self):
if not self.empty():
return self.items[len(self.items)-1]
else:
return None
# 弹栈
def pop(self):
if len(self.items) > 0:
return self.items.pop()
else:
print("栈已经为空")
return None
# 压栈
def push(self, item):
self.items.append(item)
# 把栈底元素移动到栈顶
def moveBottomToTop(s):
if s.empty():
return
top1 = s.top()
s.pop() # 弹出栈顶元素
if not s.empty():
# 递归处理不包含栈顶元素的子栈
moveBottomToTop(s)
top2 = s.top()
s.pop()
# 交换栈顶元素与子栈栈顶元素
s.push(top1)
s.push(top2)
else:
s.push(top1)
# 翻转栈
def reverse_stack(s):
if s.empty():
return
# 把栈底元素移动到栈顶
moveBottomToTop(s)
top = s.top()
s.pop()
# 递归处理子栈
reverse_stack(s)
s.push(top)
if __name__ == "__main__":
s = Stack()
s.push(5)
s.push(4)
s.push(3)
s.push(2)
s.push(1)
reverse_stack(s)
print("翻转后出栈顺序为:", end='')
while not s.empty():
print(s.top(), '', end='')
s.pop()
复杂度分析
- 时间复杂度都为 O ( n 2 ) O(n^2) O(n2)
- 空间复杂度为 O ( n ) O(n) O(n)
参考文献
[1] 何海涛. 剑指Offer:名企面试官精讲典型编程题(第2版). 北京: 电子工业出版社,2017
[2] 张波,楚秦. Python程序员面试算法宝典. 北京:机械工业出版社,2018