232.用栈实现队列(LeetCode)

简介: 232.用栈实现队列(LeetCode)

996a8306385c43f7975eb636b089ac1d.png


思路

思路:利用两个栈实现队列先进先出的特性,先将元素导入一个栈内

8cc36352ac4143769f49124041dec077.png


模拟出队时,则将所有元素导入另一个栈内,此时元素顺序被反转过来,只需要取栈顶数据即可

85f38ebf98e5466eb7fbbc879e66c4a4.png


那我们就可以将两个栈的功能分开,一个专门入push,一个专门出pop。出数据时,如果popst为空,则将pushst的数据导入。


假设pushst入了1234后,反转到popst后,pushst又入了56,这时也是可以的。因为先pop4次,将1 2 3 4依次出栈,popst为空,则再将56导入,再pop2次,以5 6依次出栈。最终依然是1 2 3 4 5 6先入72416f4740ef425fb6174221627092fe.png先出的顺序。



实现

实现: 因为C语言没有库可以现成使用,所以我们将写好的栈导入


先创建MyQueue结构体,包含两个栈结构体。再malloc动态申请MyQueue结构体的空间,最后将两个栈传入初始化函数,进行初始化(记得要加上&取地址符号)


5f3aa861b04b4469977f2d9c8779b387.png

入队过程 ,我们把数据全部导入pushst栈内即可

8907c5d5762a494f8271e70c2dd3cb6c.png


因为peek的功能比较简单,只用返回队列开头元素,所以我们先实现这个功能,等会实现pop再复用peek。


返回队列开头元素,我们的核心思路,先判断popst是否为空,如果为空,则循环将pushst中的元素全部导入popst(注意:每取出一个栈顶元素,就将该元素pop出栈),最后获取popst的栈顶元素即可

29d46f55f4f84997af7e57e5fffbe129.png


出队过程,复用peek的功能,先用front保存队头元素,再将popst的栈顶元素弹出,最后返回front即可

4e37f049c7174c0bb923cde6e70e2d23.png


判断栈是否为空,只要当两个栈pushst和popst全为空时,队列才为空,返回true,否则返回false

c3a34f4a62124dfc97897069a9423250.png


最后,释放队列空间,可能有人只写了最后一句也给过了,但是其实这是不对的。正确做法是,先将两个栈都销毁(销毁数组),再将MyQueue空间给释放掉,这样才不会造成内存泄漏

71f135a5d201489397f2e975b6a643d7.png


完整代码附上:


typedef int STDataType;
typedef struct Stack
{
  STDataType* a;
  int top;
  int capacity;
}ST;
//初始化
void STInit(ST* pst);
//销毁
void STDestroy(ST* pst);
//压栈
void STPush(ST* pst, STDataType x);
//出栈
void STPop(ST* pst);
//获取栈顶元素
STDataType STTop(ST* pst);
//检测栈是否为空
bool STEmpty(ST* pst);
//检测栈中有效元素个数
int STSize(ST* pst);
void STInit(ST* pst)
{
  assert(pst);
  pst->a = NULL;
  pst->top = 0;//top指向栈顶元素的下一个位置
  pst->capacity = 0;
}
void STDestroy(ST* pst)
{
  assert(pst);
  free(pst->a);
  pst->top = pst->capacity = 0;
}
void STPush(ST* pst, STDataType x)
{
  assert(pst);
  if (pst->top == pst->capacity)
  {
  int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
  STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));
  if (tmp == NULL)
  {
    perror("realloc fail");
    return;
  }
  pst->a = tmp;
  pst->capacity = newCapacity;
  }
  pst->a[pst->top++] = x;
}
void STPop(ST* pst)
{
  assert(pst);
  assert(!STEmpty(pst));
  pst->top--;
}
STDataType STTop(ST* pst)
{
  assert(pst);
  assert(!STEmpty(pst));
  return pst->a[pst->top - 1];
}
bool STEmpty(ST* pst)
{
  assert(pst);
  return pst->top == 0;
}
int STSize(ST* pst)
{
  assert(pst);
  return pst->top;
}
typedef struct {
    ST pushst;
    ST popst;
} MyQueue;
MyQueue* myQueueCreate() {
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    if (obj == NULL)
    {
        perror("malloc fail");
        return NULL;
    }
    STInit(&obj->pushst);
    STInit(&obj->popst);
    return obj;
}
void myQueuePush(MyQueue* obj, int x) {
    STPush(&obj->pushst, x);
}
int myQueuePop(MyQueue* obj) {
    int front = myQueuePeek(obj);
    STPop(&obj->popst);
    return front;
}
int myQueuePeek(MyQueue* obj) {
    if (STEmpty(&obj->popst))
    {
        while (!STEmpty(&obj->pushst))
        {
            STPush(&obj->popst, STTop(&obj->pushst));
            STPop(&obj->pushst);
        }
    }
    return STTop(&obj->popst);
}
bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->pushst)
    && STEmpty(&obj->popst);
}
void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->pushst);
    STDestroy(&obj->popst);
    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);
*/
相关文章
|
2月前
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
12 0
|
2月前
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
25 0
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
33 4
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 09. 用两个栈实现队列
使用两个栈实现队列的Python解决方案,包括初始化两个栈、实现在队列尾部添加整数的appendTail方法和在队列头部删除整数的deleteHead方法,以及相应的示例操作。
41 2
|
4月前
|
Python
【Leetcode刷题Python】641.循环双端队列
文章介绍了如何实现一个循环双端队列,包括其操作如插入、删除、获取队首和队尾元素,以及检查队列是否为空或已满,并提供了Python语言的实现代码。
25 0
|
4月前
|
Python
【Leetcode刷题Python】232. 用栈实现队列
如何使用Python语言通过两个栈来实现队列的所有基本操作,包括入队(push)、出队(pop)、查看队首元素(peek)和判断队列是否为空(empty),并提供了相应的代码实现。
22 0
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
63 6
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
125 2
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
43 1