⭐算法入门⭐《栈 和 队列》简单01 —— LeetCode 232. 用栈实现队列
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⭐算法入门⭐《栈 和 队列》简单01 —— LeetCode 232. 用栈实现队列相关的知识,希望对你有一定的参考价值。
🙉饭不食,水不饮,题必须刷🙉
C语言免费动漫教程,和我一起打卡! 🌞《光天化日学C语言》🌞
LeetCode 太难?先看简单题! 🧡《C语言入门100例》🧡
数据结构难?不存在的! 🌳《画解数据结构》🌳
LeetCode 太简单?算法学起来! 🌌《夜深人静写算法》🌌
一、题目
1、题目描述
仅使用两个栈实现 先入先出 队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现 MyQueue 类:
void push(int x)
将元素 x 推到队列的末尾
int pop()
从队列的开头移除并返回元素
int peek()
返回队列开头的元素
boolean empty()
如果队列为空,返回 true ;否则,返回 false
说明:
只能使用标准的栈操作。实现每个操作均摊时间复杂度为 O ( 1 ) O(1) O(1) 的队列?换句话说,执行 n n n 个操作的总时间复杂度为 O ( n ) O(n) O(n),即使其中一个操作可能花费较长时间。
样例输入:["MyQueue", "push", "push", "peek", "pop", "empty"] [[], [1], [2], [], [], []]
样例输出:[null, null, null, 1, 1, false]
2、基础框架
- C语言版本 给出的基础框架代码如下:
typedef struct {
} MyQueue;
/** Initialize your data structure here. */
MyQueue* myQueueCreate() {
}
/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
}
/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
}
/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
}
/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
}
void myQueueFree(MyQueue* obj) {
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/
3、原题链接
( 1 ) (1) (1) LeetCode 232. 用栈实现队列
( 2 ) (2) (2) 剑指 Offer 09. 用两个栈实现队列
( 3 ) (3) (3) 面试题 03.04. 化栈为队
二、解题报告
1、思路分析
- 考虑用两个栈,一个用来 push;一个用来 pop;
- 当 push 操作的时候,只需要无脑 入栈 即可;
- 当 pop 操作时,先要判断栈中是否有元素,如果没有,则一次性将 push 栈中的元素都 pop 出来,并且 入栈到 pop 栈中,再执行 pop 操作;
- 有关 栈 的实现,可以参见以下文章:《画解数据结构》栈。
2、时间复杂度
- 任何一个元素只会在每个栈中入栈和出栈各一次,总的时间复杂度为 O ( n ) O(n) O(n)。均摊下来每次的操作就是 O ( 1 ) O(1) O(1) 的。
3、代码详解
/************************************* 栈的顺序表实现 *************************************/
#define DataType int
#define maxn 100010
struct Stack {
DataType data[maxn];
int top;
};
void StackClear(struct Stack* stk) {
stk->top = 0;
}
void StackPushStack(struct Stack *stk, DataType dt) {
stk->data[ stk->top++ ] = dt;
}
void StackPopStack(struct Stack* stk) {
--stk->top;
}
DataType StackGetTop(struct Stack* stk) {
return stk->data[ stk->top - 1 ];
}
int StackGetSize(struct Stack* stk) {
return stk->top;
}
bool StackIsEmpty(struct Stack* stk) {
return !StackGetSize(stk);
}
/************************************* 栈的顺序表实现 *************************************/
typedef struct {
struct Stack push; // (1)
struct Stack pop; // (2)
} MyQueue;
/** (3) */
MyQueue* myQueueCreate() {
MyQueue *q = (MyQueue *)malloc(sizeof(MyQueue));
StackClear(& (q->push) );
StackClear(& (q->pop) );
return q;
}
/** (4) */
void myQueuePush(MyQueue* obj, int x) {
StackPushStack( & obj->push, x );
}
/** (5) */
void myQueueCheckPop(MyQueue* obj) {
int val;
if( StackIsEmpty( & obj->pop ) ) {
while( !StackIsEmpty(& obj->push ) ) {
val = StackGetTop( &obj->push );
StackPushStack( &obj->pop, val );
StackPopStack( &obj->push );
}
}
}
/** (6) */
int myQueuePop(MyQueue* obj) {
int ret;
myQueueCheckPop(obj);
ret = StackGetTop( & obj->pop );
StackPopStack( &obj->pop );
return ret;
}
/** (7) */
int myQueuePeek(MyQueue* obj) {
int ret;
myQueueCheckPop(obj);
ret = StackGetTop( & obj->pop );
return ret;
}
/** (8) */
bool myQueueEmpty(MyQueue* obj) {
return StackIsEmpty( &obj->push ) && StackIsEmpty( &obj->pop );
}
void myQueueFree(MyQueue* obj) {
free(obj);
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/
- ( 1 ) (1) (1) 入队操作时 入栈 到 push栈 中;
- ( 2 ) (2) (2) 出队操作时 从 pop栈 进行 弹栈;
-
(
3
)
(3)
(3)
myQueueCreate
:申请内存,对两个栈进行初始化; -
(
4
)
(4)
(4)
myQueuePush
:将元素 入栈 到 push栈 中; -
(
5
)
(5)
(5)
myQueueCheckPop
:将 push栈 中的数据 弹栈,再入栈 到 pop栈 中; -
(
6
)
(6)
(6)
myQueuePop
:先执行myQueueCheckPop
,再从 pop栈 进行 弹栈; -
(
7
)
(7)
(7)
myQueuePeek
:先执行myQueueCheckPop
,再从 pop栈 取 栈顶元素 返回; - ( 8 ) (8) (8) 两个栈均为空才认为这个队列为空;
三、本题小知识
我们在考虑问题的时候,往往可以将一个问题和另一个问题联系起来,将另一个子问题抽成一个子函数,这样就可以屏蔽子函数的实现细节。
以上是关于⭐算法入门⭐《栈 和 队列》简单01 —— LeetCode 232. 用栈实现队列的主要内容,如果未能解决你的问题,请参考以下文章
⭐算法入门⭐《栈 和 队列》简单02 —— LeetCode 225. 用队列实现栈
⭐算法入门⭐《栈 - 单调栈》简单01 —— LeetCode 155. 最小栈
⭐算法入门⭐《栈》简单01 —— LeetCode 20. 有效的括号
⭐算法入门⭐《队列》简单01 —— LeetCode 933. 最近的请求次数