@@ -11,78 +11,66 @@ push(x) -- 将一个元素放入队列的尾部。
11
11
pop() -- 从队列首部移除元素。
12
12
peek() -- 返回队列首部的元素。
13
13
empty() -- 返回队列是否为空。
14
-
15
-
16
14
示例:
17
15
18
16
MyQueue queue = new MyQueue();
19
17
20
18
queue.push(1);
21
19
queue.push(2);
22
- queue.peek(); // 返回 1
23
- queue.pop(); // 返回 1
20
+ queue.peek(); // 返回 1
21
+ queue.pop(); // 返回 1
24
22
queue.empty(); // 返回 false
25
-
26
-
27
23
说明:
28
24
29
- 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
25
+ 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
30
26
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
31
- 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
32
-
27
+ 假设所有操作都是有效的、 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
33
28
```
34
29
35
30
## 前置知识
36
31
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
+ - 队列
47
34
48
35
## 思路
49
36
50
- 这道题目是让我们用栈来模拟实现队列。 我们知道栈和队列都是一种受限的数据结构。
51
- 栈的特点是只能在一端进行所有操作,队列的特点是只能在一端入队,另一端出队。
37
+ 题目要求用栈的原生操作来实现队列,也就是说需要用到 pop 和 push
38
+ 但是我们知道 pop 和 push 都是在栈顶的操作,而队列的 enque 和 deque 则是在队列的两端的操作,这么一看一个 stack 好像不太能完成。
39
+
40
+ 我们来分析一下过程。
52
41
53
- 在这里我们可以借助另外一个栈,也就是说用两个栈来实现队列的效果。这种做法的时间复杂度和空间复杂度都是 O(n)。
42
+ 假如向栈中分别 push 四个数字 ` 1, 2, 3, 4 ` ,那么此时栈的情况应该是:
54
43
55
- 由于栈只能操作一端,因此我们 peek 或者 pop 的时候也只去操作顶部元素,要达到目的
56
- 我们需要在 push 的时候将队头的元素放到栈顶即可。
44
+ ![ ] ( https://pic.leetcode-cn.com/1614914197-xJWIpb-0081Kckwly1glwx3qnz9oj30760dyq39.jpg )
57
45
58
- 因此我们只需要在 push 的时候,用一下辅助栈即可。
59
- 具体做法是先将栈清空并依次放到另一个辅助栈中,辅助栈中的元素再次放回栈中,最后将新的元素 push 进去即可。
46
+ 如果此时按照题目要求 pop 或者 peek 的话, 应该是返回 1 才对,而 1 在栈底我们无法直接操作。如果想要返回 1,我们首先要将 2,3,4 分别出栈才行。
60
47
61
- 比如我们现在栈中已经是 1,2,3,4 了。 我们现在要 push 一个 5.
48
+ ![ ] ( https://pic.leetcode-cn.com/1614914197-RzHCxu-0081Kckwly1glwx3yd0blj31yi0joq5p.jpg )
62
49
63
- push 之前是这样的:
50
+ 然而,如果我们这么做,1 虽然是正常返回了,但是 2,3,4 不就永远消失了么? 一种简答方法就是,将 2,3,4 ** 存 ** 起来。而题目又说了,只能使用栈这种数据结构,那么我们考虑使用一个额外的栈来存放弹出的 2,3,4。
64
51
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 出来不扔掉,而是存起来)
66
54
67
- 然后我们将栈中的元素转移到辅助栈 :
55
+ 整个过程类似这样 :
68
56
69
- ![ 232.implement-queue-using-stacks.drawio ] ( https://tva1.sinaimg.cn/large/007S8ZIlly1ghlu88r2h6j308p07c74k .jpg )
57
+ ![ ] ( https://pic.leetcode-cn.com/1614914197-mcKlvh-0081Kckwly1glwx4cnke3j30pg0j0dgx .jpg )
70
58
71
- 最后将新的元素添加到栈顶。
59
+ 比如,这个时候,我们想 push 一个 5,那么大概就是这样的:
72
60
73
- ![ 232.implement-queue-using-stacks.drawio ] ( https://tva1.sinaimg.cn/large/007S8ZIlly1ghlu898h4rj309t07074l .jpg )
61
+ ![ ] ( https://pic.leetcode-cn.com/1614914197-CvfelO-007S8ZIlly1gfhu6exrzyj327g0u0gu9 .jpg )
74
62
75
- 整个过程是这样的:
63
+ 然而这一过程,我们也可以发生在 push 阶段。
76
64
77
- ![ 232.implement-queue-using-stacks.drawio ] ( https://tva1.sinaimg.cn/large/007S8ZIlly1ghlu89mjsjj30jg0czaba.jpg )
65
+ 总之,就是我们需要在 push 或者 pop 的时候,将数组在两个栈之间倒腾一次。
78
66
79
- ## 关键点解析
67
+ ## 关键点
80
68
81
69
- 在 push 的时候利用辅助栈(双栈)
82
70
83
71
## 代码
84
72
85
- - 语言支持:JS, Python, Java, Go
73
+ - 语言支持:JS, Python, Java
86
74
87
75
Javascript Code:
88
76
@@ -253,57 +241,10 @@ class MyQueue {
253
241
*/
254
242
```
255
243
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
-
303
244
** 复杂度分析**
304
245
305
- - 时间复杂度:$O(1)$
306
- - 空间复杂度:$O(1)$
246
+ - 时间复杂度:< code >O(N)</ code >,其中 N 为 栈中元素个数,因为每次我们都要倒腾一次。
247
+ - 空间复杂度:< code >O(N)</ code >,其中 N 为 栈中元素个数,多使用了一个辅助栈,这个辅助栈的大小和原栈的大小一样。
307
248
308
249
## 扩展
309
250
@@ -322,8 +263,6 @@ func (this *MyQueue) Transfer() {
322
263
323
264
- [ further reading] ( https://stackoverflow.com/questions/2050120/why-use-two-stacks-to-make-a-queue/2050402#2050402 )
324
265
325
- 更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。
326
-
327
- 关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
266
+ 更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。
328
267
329
- ![ ] ( https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg )
268
+ 大家也可以关注我的公众号《力扣加加》获取更多更新鲜的 LeetCode 题解
0 commit comments