04:栈

算法面试其他篇

目录:

1.1 用两个栈实现一个队列

    注:栈后进先出,列表先进先出, 使用两个栈模拟列队列未被插入元素和删除队列头

  1、实现方法

    1)使用stack1模拟队列尾部追加元素

        1. 只要追加元素直接加入stack1这个栈即可

    2)使用stack2模拟删除队首元素

        1. 当第一次删除时,stack2肯定为空,那么将stack1中元素依次出栈,加入stack2中

        2. 那么stack2中栈顶元素即是stack1中以前的栈底元素(队列头),stack1为空

        3. 当第二次删除时首先会判断stack2是否为空,如果不为空,直接删除stack2的栈顶元素即为队列头部元素

        4. 如果stack2为空,再次将stack1中元素依次加入stack2中

#!/usr/bin/env python
# -*- coding:utf-8 -*-

class CQueue:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []

    def append_tail(self, elem):
        self.stack1.append(elem)

    def delete_head(self):
        if not self.stack2:  # 如果stack2为空就将stack1中的元素依次如stack2的栈,stack2就可以模拟这个列表了
            if self.stack1:
                while self.stack1:
                    elem = self.stack1.pop()
                    self.stack2.append(elem)
            else:
                raise Exception("Queue is empty.")
        elem = self.stack2.pop()  # 只要stack2不为空,stack2栈顶元素即是队首元素
        return elem


if __name__ == '__main__':
    que = CQueue()
    que.append_tail(1)
    que.append_tail(2)
    que.append_tail(3)
    print que.delete_head()  # 1
    que.append_tail(4)
模拟队列(双栈)
'''模拟 1 2 3 加入对了,然后3出对了,然后4加入队列过程'''
# 第一步:1 2 3 加入队列
'''
stack1 = [1,2,3]
'''

# 第二步:删除队列头部元素
'''
1) 将stack1中元素依次出栈放入stack2中
stack1 = []
stack2 = [3,2,1]
删除队列首部元素即删除stack2栈顶元素: stack2 = [3,2]
'''

# 第三步:将4加入队列
'''
stack1 = [4]
stack2 = [3,2]
# 如果再次删除队列头部,就直接删除stack2栈顶元素,直到stack2为空,再次将stack1中元素出栈放入stack2即可
'''
原理推倒

 1.2 python实现栈在 O(1) 时间内求 min

  1、题目说明

      1. python的栈是用list实现的,只要将list的append和pop封装到stack类中,即实现了压栈和退栈。

      2. 可以考虑利用两个栈来实现,一个栈保存所有数据,另一个保存对应状态下的最小值。

      3. 当新压栈的元素小于等于栈内最小的元素时,将新元素压入min_list,min_list栈顶元素即为所求。

      举例:依次压栈3,2,4,1:

        stack_list = [3, 2, 4, 1]

        min_list = [3, 2, 1]

#! /usr/bin/env python
# -*- coding: utf-8 -*-

class stack(object):
    stack_list = []
    min_list = []
    min = None

    # 只有最小栈本身为空或者当前的值小于等于最小栈的栈顶时进行压栈
    def push(self, x):
        if not self.stack_list:  # 栈为空直接入栈,并将第一个值压入min_list
            self.min = x
            self.min_list.append(self.min)
            self.stack_list.append(x)
            return
        self.stack_list.append(x)
        if self.min >= x:  # 如果即将入栈元素小于当前最小元素,替换当前最小元素,并推入min_list
            self.min = x
            self.min_list.append(self.min)
        return

    # 弹出的数据等于最小栈顶的数据,最小栈的数据也要弹出
    def pop(self):
        pop_result = None
        if self.stack_list:
            pop_result = self.stack_list[-1]
            if self.stack_list.pop() == self.min:
                self.min_list.pop()
                if self.min_list:  # 取出 min_list 中最小元素作为新的最小元素
                    self.min = self.min_list[-1]
                else:
                    self.min = None
            return pop_result
        else:
            self.min = None
            return pop_result

    def print_stack(self):
        print(self.stack_list)
        return

    def get_min(self):
        return self.min

    
if '__main__' == __name__:
    s = stack()
    s.push(3)
    s.push(2)
    s.push(4)
    s.push(1)
    print s.get_min() # 1
O(1)时间求栈min

 

 

 

 

 

 

 

 

 

1111111111111111111

posted @ 2019-03-07 11:09  不做大哥好多年  阅读(148)  评论(0编辑  收藏  举报