第2章 面试需要的基础知识
第3章 高质量的代码
第4章 解决面试题的思路
面试题27 :二叉树的镜像
面试题29 :顺时针打印矩阵
面试题30 :包含min函数的栈
第5章 优化时间和空间效率
第6章 面试中的各项能力
第7章 两个面试案例
牛客网
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
解题思路
解法一:
《剑指offer》
使用辅助栈来存储最小值。O(n)空间复杂度。
步骤 | 操作 | 数据栈 | 辅助栈 | 最小值 |
---|---|---|---|---|
1 | 压入3 | 3 | 3 | 3 |
2 | 压入4 | 3,4 | 3,3 | 3 |
3 | 压入2 | 3,4,2 | 3,3,2 | 2 |
4 | 压入1 | 3,4,2,1 | 3,3,2,1 | 1 |
5 | 弹出 | 3,4,2 | 3,3,2 | 2 |
6 | 弹出 | 3,4 | 3,3 | 3 |
7 | 压入0 | 3,4,0 | 3,3,0 | 0 |
实战
代码中stack即为数据栈,min_lst即为辅助栈。
class Solution:
def __init__(self):
self.min_lst = []
self.stack = []
def push(self, node):
# write code here
self.stack.append(node)
if self.min_lst:
if node <= self.min_lst[-1]:
self.min_lst.append(node)
else:
self.min_lst.append(self.min_lst[-1])
else:
self.min_lst.append(node)
def pop(self):
# write code here
if self.stack:
self.min_lst.pop()
return self.stack.pop()
return None
def top(self):
# write code here
if self.stack:
return self.stack[-1]
return None
def min(self):
# write code here
if self.min_lst:
return self.min_lst[-1]
return None
辅助栈中因为没有新的min值入栈而产生的重复的、冗余的过往min值实际上可以舍弃掉。不过这时数据栈存储的就不是压入的原始数据了,而是原始数据与当前最小值的差值。
class Solution:
def __init__(self):
self.min_lst = []
self.stack = []
def push(self, node):
# write code here
if self.min_lst:
if node < self.min_lst[-1]:
self.min_lst.append(node)
self.stack.append(node - self.min_lst[-1])
else:
self.min_lst.append(node)
self.stack.append(node)
def pop(self):
# write code here
if self.stack:
if self.stack[-1] == 0:
self.min_lst.pop()
return self.stack.pop()
return self.stack.pop() + self.min_lst[-1]
return None
def top(self):
# write code here
if self.stack:
return self.stack[-1] + self.min_lst[-1]
return None
def min(self):
# write code here
if self.min_lst:
return self.min_lst[-1]
return None
解法二:
解法一中使用辅助栈存储最小值,最小值和数据栈是有关系的,若能找到这种关系,就可以抛弃辅助栈,达到O(1)的空间复杂度。
使用一个变量mini来存储全栈的最小值,数据栈中不在直接存原数据,而是存储原数据和当前最小值的差值,如果压入的数据小于mini则还需更新mini的值。抛出数据时,先判断数据栈中值是否大于零,若大于零则返回数据栈中的值加上mini的值;若小于零则返回mini,同时更新mini的值为mini减去数据栈的值。
压入操作:
压入的数据是value,那么存储的数据为value-mini;
弹出操作:
若当前数据栈顶端数据小于零,返回mini,同时更新mini=mini-stack[-1];
若当前数据栈顶端数据或等于零,则返回mimi+stack[-1];
步骤 | 操作 | 数据栈 | 最小值 |
---|---|---|---|
1 | 压入3 | 0 | 3 |
2 | 压入4 | 0,1 | 3 |
3 | 压入2 | 0, 1, -1 | 2 |
4 | 压入1 | 0, 1, -1, -1 | 1 |
5 | 弹出 | 0, 1, -1 | 2 |
6 | 弹出 | 0, 1 | 3 |
7 | 压入0 | 0, 1, -3 | 0 |
实战
class Solution:
def __init__(self):
self.mini = None
self._top = None
self.stack = []
def push(self, node):
# write code here
if self.stack:
self._top = node
self.stack.append(node-self.mini)
if node < self.mini:
self.mini = node
else:
self.stack.append(0)
self.mini = node
self._top = node
def pop(self):
# write code here
if self.stack:
if self.stack[-1] >= 0:
return self.mini+self.stack.pop()
minimum = self.mini
self.mini = self.mini-self.stack.pop()
return minimum
return None
def top(self):
# write code here
return self._top
def min(self):
# write code here
return self.mini