面试准备-栈和队列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vivian_ll/article/details/88186936

栈的特点就是后进先出,需要O(N)的时间才能找到栈中的最值。
队列和栈刚好相反,是先进先出,表面上和栈是一对矛盾体,但实际上,都可以利用对方来实现自己。

1.用两个栈实现一个队列

思路:
入队:元素进栈A
出队:先判断栈B是否为空,为空则将栈A中的元素 pop 出来并 push 进栈B,再栈B出栈,如不为空则栈B直接出栈
改进:
入队:元素进栈A
出队:先判断栈B是否为空,为空则将栈A中的n-1个元素 pop 出来并 push 进栈B,最先压入栈A的元素不pop再push到栈B,直接从栈A pop出栈,如不为空则栈B直接出栈
注意怎样把Queue的操作和Stack的操作联系起来

class MyQueue:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        # 初始化
        self.stack1 = Stack()
        self.stack2 = Stack()

    def push(self, x):
        """
        Push element x to the back of queue.
        :type x: int
        :rtype: void
        """
        self.stack1.items.append(x)

    def pop(self):
        """
        Removes the element from in front of queue and returns that element.
        :rtype: int
        """
        if self.stack2.isEmpty()!=True: #判断栈2是否为空
            return self.stack2.items.pop()
        else:
            if self.stack1.isEmpty()!=True:
                while self.stack1.size()!=1:
                    self.stack2.items.append(self.stack1.items.pop())
                return self.stack1.items.pop()
            else:
                if self.stack2.isEmpty() != True:
                    return self.stack2.items.pop()

    def peek(self):
        """
        Get the front element.
        :rtype: int
        """
        if self.stack2.isEmpty() != True:
            if len(self.stack2.items) >= 1:
                return self.stack2.items[len(self.stack2.items) - 1]
        else:
            if self.stack1.isEmpty() != True:
                return self.stack1.items[0]
            else:
                return False

    def empty(self):
        """
        Returns whether the queue is empty.
        :rtype: bool
        """
        return self.stack1.items == [] and self.stack2.items == []

    def size(self):
        return len(self.stack1.items)+len(self.stack2.items)

2.定义栈的数据结构,在该类型中实现一个能够得到栈的最小元素的min函数,在该栈中,要求调用min,push和pop的时间复杂度都是O(1)

我们首先的第一想法就是在每次将元素压入栈的时候,保留当前的最小值,但仔细想想,如果最小值已经被弹出栈了,又该如何得到剩下元素中的最小值呢?
我们可以使用一个辅助栈,每次压入元素的时候,将最小值压入,每次弹出元素的时候,也将最小值弹出,确保这两个栈的动作是同步的。

class MinStack:

    # def __init__(self):
    #     """
    #     initialize your data structure here.
    #     """
    #     self.stack = []
    #
    # def push(self, x: int) -> None:
    #     self.stack.append(x)
    #
    #
    # def pop(self) -> None:
    #     return self.stack.pop()
    #
    # def top(self) -> int:
    #     return self.stack[-1]
    #
    # def getMin(self) -> int:
    #     return sorted(self.stack)[0]
    # # 或    return min(self.l)

    def __init__(self):
        self.stack = []
        self.minimum = []   # 按顺序存放当前的最小值

    def push(self, x):
        self.stack.append(x)
        try:
            oldMin = self.minimum[-1]
            if x < oldMin:
                self.minimum.append(x)
            else:
                self.minimum.append(oldMin)
        except:
            self.minimum.append(x)

    def pop(self):
        self.minimum.pop()
        return (self.stack.pop())

    def top(self):
        return (self.stack[-1])

    def getMin(self):
        return (self.minimum[-1])

3.输入两个整数序列,第一个序列表示压栈顺序,判断第二个序列是否是弹出顺序

思路:
如果下一个弹出的数字刚好是栈顶数字,那么直接弹出。
如果下一个弹出的数字不在栈顶,我们把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止。
如果所有的数字都压入栈了仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。

def validateStackSequences(self, pushed, popped) -> bool:
        # 贪婪算法 均为O(N)
        j = 0
        newstack = []  # 压入栈
        for x in pushed:
            newstack.append(x)
            while newstack and newstack[-1] == popped[j]:  # popped[j]为弹出序列当前最顶上元素
                newstack.pop()
                j += 1  # 计数 当前有多少数对应上

        return j == len(popped)  # 相当于 return not newstack

猜你喜欢

转载自blog.csdn.net/vivian_ll/article/details/88186936