Python程序员面试算法宝典---解题总结: 第二章 栈、队列与哈希 2.5 如何用O(1)的时间复杂度求栈中最小元素

本文是Python程序员面试算法系列的第二章,重点讲解如何在栈中以O(1)时间复杂度获取最小元素。通过深入理解栈、队列和哈希的特性,提出了一种有效的方法来解决这个问题,对于准备面试和提升算法能力的开发者极具参考价值。
摘要由CSDN通过智能技术生成
#!/usr/bin/env python
# encoding: utf-8

'''
Python程序员面试算法宝典---解题总结:  第二章 栈、队列与哈希 2.5 如何用O(1)的时间复杂度求栈中最小元素

分析:
O(1)时间查找到最小的元素最容易实现的方式就是将最小元素始终放在栈顶,
这样每次只需要获取栈顶元素,即可获取最小元素。
那么问题的关键就是如何在压入元素的时候确保最小元素在栈顶。
一种思路就是设置两个栈,对两个栈进行操作。
举例如下: 假设入栈序列为: 5,3,4,2,1
假设有栈1为s1,栈2为s2。
将5压入s1,此时压入3之前,判断s1的栈顶元素为5,此时因为3小于5,就继续把元素3压入到s1中,
此时s1从站顶到栈顶序列如下:
s1     s2
3
5
此时判断4大于s1的栈顶元素3,此时不能插入s1中,此时将
s1中的元素全部压入s2中,直到s1的栈顶元素大于当前待压入元素4,
最后将元素4压入到s2中,此时s1,s2中元素如下:
s1      s2
5       4
        3
最后每次取出s2栈顶元素压入s2中,直到s2为空,此时s1,s2如下:
s1      s2
3
4
5

总结:
算法步骤:
步骤1: 若栈s1为空,则将当前待压入元素压入到s1中;
步骤2: 否则,如果s1非空
    2.1 如果当前待压入元素小于s1的栈顶元素,则将当前待压入元素,压入到s1中
    2.2 2.2.1) 否则,只要当前待压入元素大于s1栈顶元素,就弹出s1栈顶元素并压入到栈s2中;
        重复步骤2.2,直到s1为空或者当前待压入元素小于s1栈顶元素;
        2.2.2) 最后将当前待压入元素压入到s2中;
        2.2.3) 只要s2不空,就将s2的栈顶元素不断弹出并压入到s1中。
通过以上步骤,确保了s1中的栈顶元素始终是最小的元素,即可满足O(1)时间复杂度获取栈中最小元素

弄错了,这个是修改了栈的入栈顺序,弹出栈会出错。

书上的解法:
用另外一个栈记录最小元素。
一个元素栈保存原来的真实入栈序列;用一个min栈,
如果min栈为空,则压入当前待压入元素;
否则,如果当前待压入元素比min栈的栈顶元素小,则将当前
待压入元素压入到min栈中。
出栈的时候,真实入栈序列直接弹出栈顶元素;
对于min栈,如果待弹出元素和min栈栈顶元素相同,则弹出min栈的栈顶元素。


关键:
1 用另外一个栈记录最小元素。
一个元素栈保存原来的真实入栈序列;用一个min栈,
如果min栈为空,则压入当前待压入元素;
否则,如果当前待压入元素比min栈的栈顶元素小,则将当前
待压入元素压入到min栈中。
出栈的时候,真实入栈序列直接弹出栈顶元素;
对于min栈,如果待弹出元素和min栈栈顶元素相同,则弹出min栈的栈顶元素。

2 用两个栈来回倒腾实现的是排序栈的功能

3 记录一个min栈记录最小元素序列即可。
当前待插入元素比min栈的栈顶小就插入到min栈中。


参考:
Python程序员面试算法宝典
'''

class Stack(object):
    def __init__(self):
        self.data = list()

    def empty(self):
        result = False if self.data else True
        return result

    def push(self, data):
        self.data.append(data)

    def pop(self):
        if not self.empty():
            self.data.pop()
        else:
            info = "stack is empty, it can not pop"
            print info

    def top(self):
        if not self.empty():
            return self.data[-1]
        else:
            info = "stack is empty, it can not get top element"
            print info


class SortStack(object):
    def __init__(self):
        self.stack1 = Stack()
        self.stack2 = Stack()

    def empty(self):
        return self.stack1.empty()

    def push(self, data):
        if not self.empty():
            while not self.empty() and self.stack1.top() < data:
                top = self.stack1.top()
                if top is not None:
                    self.stack2.push(top)
                    self.stack1.pop()
            self.stack2.push(data)
            while not self.stack2.empty():
                top = self.stack2.top()
                self.stack2.pop()
                if top is not None:
                    self.stack1.push(top)
        else:
            self.stack1.push(data)

    def pop(self):
        if not self.empty():
            self.stack1.pop()
        else:
            info = "stack is empty, it can not pop"
            print info

    def min(self):
        if not self.empty():
            return self.stack1.top()
        else:
            info = "stack is empty, it can not get min element"
            print info


class MinStack(object):
    def __init__(self):
        self.elementStack = Stack()
        self.minStack = Stack()

    def empty(self):
        return self.elementStack.empty()

    def push(self, data):
        self.elementStack.push(data)
        if self.minStack.empty():
            self.minStack.push(data)
        else:
            if data < self.minStack.top():
                self.minStack.push(data)

    def min(self):
        if self.minStack.empty():
            return
        else:
            return self.minStack.top()

    def pop(self):
        if self.elementStack.empty():
            info = "stack is empty, it can not pop"
            print info
            return
        data = self.elementStack.top()
        self.elementStack.pop()
        if data == self.min() and self.min is not None:
            self.minStack.pop()

def process():
    data = [5, 3, 4, 2, 1]
    minStack = MinStack()
    for value in data:
        minStack.push(value)
        min = minStack.min()
        print min
    print "####"
    while not minStack.empty():
        minStack.pop()
        print minStack.min()


if __name__ == "__main__":
    process()

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值