Skip to content

Commit 9688a0e

Browse files
author
lucifer
committed
feat: 232 重写
1 parent c9819c3 commit 9688a0e

File tree

1 file changed

+29
-90
lines changed

1 file changed

+29
-90
lines changed

problems/232.implement-queue-using-stacks.md

Lines changed: 29 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -11,78 +11,66 @@ push(x) -- 将一个元素放入队列的尾部。
1111
pop() -- 从队列首部移除元素。
1212
peek() -- 返回队列首部的元素。
1313
empty() -- 返回队列是否为空。
14-
 
15-
1614
示例:
1715
1816
MyQueue queue = new MyQueue();
1917
2018
queue.push(1);
2119
queue.push(2);
22-
queue.peek(); // 返回 1
23-
queue.pop(); // 返回 1
20+
queue.peek(); // 返回 1
21+
queue.pop(); // 返回 1
2422
queue.empty(); // 返回 false
25-
 
26-
2723
说明:
2824
29-
你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
25+
你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
3026
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
31-
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
32-
27+
假设所有操作都是有效的、 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
3328
```
3429

3530
## 前置知识
3631

37-
- [](https://github.com/azl397985856/leetcode/blob/master/thinkings/basic-data-structure.md)
38-
39-
## 公司
40-
41-
- 阿里
42-
- 腾讯
43-
- 百度
44-
- 字节
45-
- bloomberg
46-
- microsoft
32+
-
33+
- 队列
4734

4835
## 思路
4936

50-
这道题目是让我们用栈来模拟实现队列。 我们知道栈和队列都是一种受限的数据结构。
51-
栈的特点是只能在一端进行所有操作,队列的特点是只能在一端入队,另一端出队。
37+
题目要求用栈的原生操作来实现队列,也就是说需要用到 pop 和 push
38+
但是我们知道 pop 和 push 都是在栈顶的操作,而队列的 enque 和 deque 则是在队列的两端的操作,这么一看一个 stack 好像不太能完成。
39+
40+
我们来分析一下过程。
5241

53-
在这里我们可以借助另外一个栈,也就是说用两个栈来实现队列的效果。这种做法的时间复杂度和空间复杂度都是 O(n)。
42+
假如向栈中分别 push 四个数字 `1, 2, 3, 4`,那么此时栈的情况应该是:
5443

55-
由于栈只能操作一端,因此我们 peek 或者 pop 的时候也只去操作顶部元素,要达到目的
56-
我们需要在 push 的时候将队头的元素放到栈顶即可。
44+
![](https://pic.leetcode-cn.com/1614914197-xJWIpb-0081Kckwly1glwx3qnz9oj30760dyq39.jpg)
5745

58-
因此我们只需要在 push 的时候,用一下辅助栈即可。
59-
具体做法是先将栈清空并依次放到另一个辅助栈中,辅助栈中的元素再次放回栈中,最后将新的元素 push 进去即可。
46+
如果此时按照题目要求 pop 或者 peek 的话, 应该是返回 1 才对,而 1 在栈底我们无法直接操作。如果想要返回 1,我们首先要将 2,3,4 分别出栈才行。
6047

61-
比如我们现在栈中已经是 1,2,3,4 了。 我们现在要 push 一个 5.
48+
![](https://pic.leetcode-cn.com/1614914197-RzHCxu-0081Kckwly1glwx3yd0blj31yi0joq5p.jpg)
6249

63-
push 之前是这样的:
50+
然而,如果我们这么做,1 虽然是正常返回了,但是 2,3,4 不就永远消失了么? 一种简答方法就是,将 2,3,4 **** 起来。而题目又说了,只能使用栈这种数据结构,那么我们考虑使用一个额外的栈来存放弹出的 2,3,4。
6451

65-
![232.implement-queue-using-stacks.drawio](https://tva1.sinaimg.cn/large/007S8ZIlly1ghlu87p5vuj30c2067dg5.jpg)
52+
![](https://pic.leetcode-cn.com/1614914197-ifsUDV-0081Kckwly1glwx43ax3xj31jm0u042t.jpg)
53+
(pop 出来不扔掉,而是存起来)
6654

67-
然后我们将栈中的元素转移到辅助栈
55+
整个过程类似这样
6856

69-
![232.implement-queue-using-stacks.drawio](https://tva1.sinaimg.cn/large/007S8ZIlly1ghlu88r2h6j308p07c74k.jpg)
57+
![](https://pic.leetcode-cn.com/1614914197-mcKlvh-0081Kckwly1glwx4cnke3j30pg0j0dgx.jpg)
7058

71-
最后将新的元素添加到栈顶。
59+
比如,这个时候,我们想 push 一个 5,那么大概就是这样的:
7260

73-
![232.implement-queue-using-stacks.drawio](https://tva1.sinaimg.cn/large/007S8ZIlly1ghlu898h4rj309t07074l.jpg)
61+
![](https://pic.leetcode-cn.com/1614914197-CvfelO-007S8ZIlly1gfhu6exrzyj327g0u0gu9.jpg)
7462

75-
整个过程是这样的:
63+
然而这一过程,我们也可以发生在 push 阶段。
7664

77-
![232.implement-queue-using-stacks.drawio](https://tva1.sinaimg.cn/large/007S8ZIlly1ghlu89mjsjj30jg0czaba.jpg)
65+
总之,就是我们需要在 push 或者 pop 的时候,将数组在两个栈之间倒腾一次。
7866

79-
## 关键点解析
67+
## 关键点
8068

8169
- 在 push 的时候利用辅助栈(双栈)
8270

8371
## 代码
8472

85-
- 语言支持:JS, Python, Java, Go
73+
- 语言支持:JS, Python, Java
8674

8775
Javascript Code:
8876

@@ -253,57 +241,10 @@ class MyQueue {
253241
*/
254242
```
255243

256-
Go Code:
257-
258-
```go
259-
type MyQueue struct {
260-
StackPush []int
261-
StackPop []int
262-
}
263-
264-
/** Initialize your data structure here. */
265-
func Constructor() MyQueue {
266-
return MyQueue{}
267-
}
268-
269-
/** Push element x to the back of queue. */
270-
func (this *MyQueue) Push(x int) {
271-
this.StackPush = append(this.StackPush, x)
272-
}
273-
274-
/** Removes the element from in front of queue and returns that element. */
275-
func (this *MyQueue) Pop() int {
276-
this.Transfer()
277-
var x int
278-
x, this.StackPop = this.StackPop[0], this.StackPop[1:]
279-
return x
280-
}
281-
282-
/** Get the front element. */
283-
func (this *MyQueue) Peek() int {
284-
this.Transfer()
285-
return this.StackPop[0]
286-
}
287-
288-
/** Returns whether the queue is empty. */
289-
func (this *MyQueue) Empty() bool {
290-
return len(this.StackPop) == 0 && len(this.StackPush) == 0
291-
}
292-
293-
// StackPush 不为空的时候, 转移到 StackPoP 中
294-
func (this *MyQueue) Transfer() {
295-
var x int
296-
for len(this.StackPush)>0 {
297-
x, this.StackPush = this.StackPush[0], this.StackPush[1:] // pop
298-
this.StackPop = append(this.StackPop, x) // push
299-
}
300-
}
301-
```
302-
303244
**复杂度分析**
304245

305-
- 时间复杂度:$O(1)$
306-
- 空间复杂度:$O(1)$
246+
- 时间复杂度:<code>O(N)</code>,其中 N 为 栈中元素个数,因为每次我们都要倒腾一次。
247+
- 空间复杂度:<code>O(N)</code>,其中 N 为 栈中元素个数,多使用了一个辅助栈,这个辅助栈的大小和原栈的大小一样。
307248

308249
## 扩展
309250

@@ -322,8 +263,6 @@ func (this *MyQueue) Transfer() {
322263

323264
- [further reading](https://stackoverflow.com/questions/2050120/why-use-two-stacks-to-make-a-queue/2050402#2050402)
324265

325-
更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。
326-
327-
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
266+
更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。
328267

329-
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg)
268+
大家也可以关注我的公众号《力扣加加》获取更多更新鲜的 LeetCode 题解

0 commit comments

Comments
 (0)