剑指offer-20 包含min函数的栈
一、题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
比如:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.
二、解题步骤
1.解题思路
普通栈的 push() 和 pop() 函数的复杂度为 O(1);而获取栈最小值 min() 函数需要遍历整个栈,复杂度为 O(N) 。
本题难点: 将 min() 函数复杂度降为 O(1),可通过建立辅助栈实现;
数据栈 A : 栈 A 用于存储所有元素,保证入栈 push() 函数、出栈 pop() 函数、获取栈顶 top() 函数的正常逻辑。
辅助栈 B : 栈 B中存储栈 A中所有 非严格降序 的元素,则栈 A中的最小元素始终对应栈 B的栈顶元素,即 min() 函数只需返回栈 B的栈顶元素即可。
因此,只需设法维护好栈 B的元素,使其保持非严格降序,即可实现 min() 函数的 O(1)复杂度。
函数设计:
(1)push(x):将数据x压入栈stack中。此时如果辅助栈as_stack是空的或者是x小于辅助栈的栈顶元素,则将x压入辅助栈(as_stack.append(x))
(2)pop(x):栈顶元素从栈中被永久性地删除。需要主要的是栈stack和辅助栈as_stack中的元素pop的一致性。如果弹出的stack中的元素与辅助栈as_stack中的栈顶元素(stack、as_stack中最小的元素)相同,那辅助栈也需要执行pop()操作,保证最小元素的一致性。
(3)top() 函数: 直接返回栈的栈顶元素即可,即返回 stack.peek() ,peek() 方法则只返回栈顶元素, 而不删除它.
(4)min() 函数: 直接返回栈的栈顶元素即可,即返回 as_stack.peek() 。
2.代码实现
# -*- coding:utf-8 -*-
class Solution:
#定义两个栈,需要一个辅助栈
def __init__(self):
self.stack=[]
self.as_stack=[]
def push(self, node):
#压数字进栈
self.stack.append(node)
#如果此时辅助栈是空栈或者压进1栈的元素小于辅助栈的第一个元素,则在辅助栈中添加
if not self.as_stack or self.as_stack[-1]>=node:
self.as_stack.append(node)
def pop(self):
#pop是向外弹出
if self.stack.pop()==self.as_stack[-1]:
self.as_stack.pop()
def top(self):
# write code here
#取出当前栈的栈顶元素
if self.stack:
return self.stack[-1]
def min(self):
# write code here
if self.as_stack:
return self.as_stack[-1]
3. 总结
取出栈中的最小值,需要借助辅助栈以空间换时间,时间复杂度为O(1)。