Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【每日一题】- 2020-03-01 - 225. 用队列实现栈 #315

Closed
azl397985856 opened this issue Mar 1, 2020 · 2 comments
Closed

【每日一题】- 2020-03-01 - 225. 用队列实现栈 #315

azl397985856 opened this issue Mar 1, 2020 · 2 comments

Comments

@azl397985856
Copy link
Owner

@azl397985856 azl397985856 commented Mar 1, 2020

使用队列实现栈的下列操作:

push(x) -- 元素 x 入栈
pop() -- 移除栈顶元素
top() -- 获取栈顶元素
empty() -- 返回栈是否为空
注意:

你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-stack-using-queues
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

@azl397985856
Copy link
Owner Author

@azl397985856 azl397985856 commented Mar 1, 2020

双队列

思路

本题和232. 用栈实现队列 思想稍有不同。 相同之处在于都可以采用双xx来解决。而这道题稍微难一点。

需要明确一点的是,本题我使用python的数组来模拟队列。Python 中 pop(0) 表示从数组头删除一个元素, append(x) 表示向数组尾部添加一个元素。 也就是说除了这两个API,我们不可以用别的数组api,当然也不可以直接用索引来操作,这都是不允许的。

  • 我们初始化两个队列q1和q2。其中q1是主队列,q2是辅助队列。
  • push往q1末尾添加元素
  • pop的时候,q1往q2转移,直到q1只剩下最后一个元素。我们将其返回即可。最后我们调换q1和q2
  • top的时候我们复用pop,这样我们的q1实际上会少一个元素,我们再将其append回去即可。
  • empty只需要判断q1是否为空即可

代码

class MyStack:

    def __init__(self):
        self.q1 = []
        self.q2 = []


    def push(self, x: int) -> None:
        self.q1.append(x)


    def pop(self) -> int:
        while len(self.q1) > 1:
            self.q2.append(self.q1.pop(0))
        self.q1, self.q2 = self.q2, self.q1
        return self.q2.pop(0)


    def top(self) -> int:
        ans = self.pop()
        self.q1.append(ans)
        return ans
        


    def empty(self) -> bool:
        return len(self.q1) == 0

复杂度分析

  • 时间复杂度:ppo 和 top 为 $O(N)$, push, empty 为 $O(1)$
  • 空间复杂度:$O(N)$

一个队列

思路

实际上q2可以不存在,我们假想一个q2队列,将q1队列本身看成q2。 这样我们只需要将上面的pop方法稍加改造即可,其他代码不需要变化,具体见下方代码区。

代码

class MyStack:

    def __init__(self):
        self.q1 = []


    def push(self, x: int) -> None:
        self.q1.append(x)


    def pop(self) -> int:
        n = len(self.q1)
        for _ in range(n - 1):
            self.q1.append(self.q1.pop(0))
        return self.q1.pop(0)


    def top(self) -> int:
        ans = self.pop()
        self.q1.append(ans)
        return ans
        


    def empty(self) -> bool:
        return len(self.q1) == 0

复杂度分析

  • 时间复杂度:ppo 和 top 为 $O(N)$, push, empty 为 $O(1)$
  • 空间复杂度:$O(1)$

延伸阅读

实际上现实中也有使用两个栈来实现队列的情况,那么为什么我们要用两个stack来实现一个queue?

其实使用两个栈来替代一个队列的实现是为了在多进程中分开对同一个队列对读写操作。一个栈是用来读的,另一个是用来写的。当且仅当读栈满时或者写栈为空时,读写操作才会发生冲突。

当只有一个线程对栈进行读写操作的时候,总有一个栈是空的。在多线程应用中,如果我们只有一个队列,为了线程安全,我们在读或者写队列的时候都需要锁住整个队列。而在两个栈的实现中,只要写入栈不为空,那么push操作的锁就不会影响到pop

欢迎关注我的公众号《脑洞前端》获取更多更新鲜的LeetCode题解

@stale
Copy link

@stale stale bot commented Apr 30, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Apr 30, 2020
@stale stale bot closed this May 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.