牛客网在线编程专题《剑指offer-面试题21》包含min函数的栈

微信公众号

题目链接:

https://www.nowcoder.com/practice/4c776177d2c04c2494f2555c9fcc1e49?tpId=13&tqId=11173&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题目描述:

解题思路:

        看到这个问题, 我们的第一反应可能是每次压入一个新元素进栈时, 将栈里的所有元素排序, 让最小的元素位于栈顶, 这样就能在0(1)时间得到最小元素了。 但这种思路不能保证最后压入栈的元素能够最先出栈, 因此这个数据结构已经不是栈了。

        我们接着想到在栈里添加一个成员变量存放最小的元素。 每次压入一个新元素进栈的时候,如果该元素比当前最小的元素还要小,则更新最小元素。 面试官听到这种思路之后就会问: 如果当前最小的元素被弹出栈了, 如何得到下一个最小的元素呢?

        分析到这里我们发现仅仅添加一个成员变量存放最小元素是不够的,也就是说当最小元素被弹出栈的时候, 我们希望能够得到次小元素。 因此在压入这个最小元素之前, 我们要把次小元素保存起来。

        是不是可以把每次的最小元素(之前的最小元素和新压入栈的元素两者的较小值)都保存起来放到另外一个辅助栈里呢?我们不妨举几个例子来分析一下把元素压入或者弹出栈的过程(如表1所示)。
        首先住空的数据栈里压入数字3, 显然现在3是最小值, 我们也把这个最小值压入辅助栈。 接下来往数据栈里压入数字4。 由于4大于之前的最小值, 因此我们仍然往辅助栈里压入数字3。第三步继续往数据栈里压入数字2。由于2 小于之前的最小值 3,因此我们把最小值更新为2,并把2压入辅助栈。同样当压入数字1时,也要更新最小值,并把新的最小值1压入辅助栈。

表1 栈内压入3、4、2、1之后接连两次弹出栈顶数字再压入0时,数据栈、辅助栈和最小值的状态
步骤 操作 数据栈 辅助栈 最小值
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

       从表1中我们可以看出,如果每次都把最小元素压入辅助栈,那么就能保证辅助栈的栈顶一直都是最小元素。当最小元素从数据栈内被弹出之后, 同时弹出辅助栈的栈顶元素,此时辅助栈的新栈顶元素就是下一个最小值。比如第四步之后,栈内的最小元素是1。当第五步在数据栈内弹出1后,我们把辅助栈的栈顶弹出, 辅助栈的栈顶元素2就是新的最小元素。接下来继续弹出数据栈和辅助栈的栈顶之后,数据栈还剩下 3、4 两个数字,3是最小值。 此时位于辅助栈的栈顶数字正好也是3,的确是最小值。 这说明我们的思路是正确的。

已经AC的代码:

'''
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
'''
class Solution:

    def __init__(self):
        self.stack = []
        self.minStack = []
        self.min_num = None

    def push(self, node):
        # write code here
        self.stack.append(node)
        if self.min_num is None:
            self.min_num = node
            self.minStack.append(self.min_num)
        elif self.min_num < node:
            self.minStack.append(self.min_num)
        else:
            self.min_num = node
            self.minStack.append(node)

    def pop(self):
        # write code here
        if len(self.stack) > 0 and len(self.minStack):
            self.minStack.pop()
            self.stack.pop()

    def top(self):
        # write code here
        return

    def min(self):
        # write code here
        return self.minStack[-1]

if __name__ == '__main__':
    stack = Solution()
    current_stack = [11, 7, 8, 9, 5, 12, 15]
    for num in (current_stack):
        stack.push(num)
    print(stack.min(), stack.stack)
    print(stack.minStack)
    # 测试用例
    # 输入一个比最小值大的
    stack.push(7)
    print(stack.min(), stack.stack)

    # 输入一个比最小值小的
    stack.push(4)
    print(stack.min(), stack.stack)

    # 弹出最小值
    stack.pop()
    print(stack.min(), stack.stack)

    # 弹出非最小值
    stack.pop()
    print(stack.min(), stack.stack)
发布了285 篇原创文章 · 获赞 892 · 访问量 111万+

猜你喜欢

转载自blog.csdn.net/program_developer/article/details/98544623
今日推荐