【LeetCode刷题日志】232.用栈实现队列

简介: 【LeetCode刷题日志】232.用栈实现队列

1.题目描述

OJ链接leetcode 题号:232.用栈实现队列】【难度:简单】

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入:

["MyQueue", "push", "push", "peek", "pop", "empty"]

[[], [1], [2], [], [], []]

输出:

[null, null, null, 1, 1, false]


解释:

MyQueue myQueue = new MyQueue();

myQueue.push(1); // queue is: [1]

myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)

myQueue.peek(); // return 1

myQueue.pop(); // return 1, queue is [2]

myQueue.empty(); // return false

提示:

  • 1 <= x <= 9
  • 最多调用 100pushpoppeekempty
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

进阶:

  • 你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

2.解题思路+代码实现

方法:双栈
思路及算法:

将一个栈当作输入栈,用于压入push传入的数据;另一个栈当作输出栈,用于 pop和peek操作。

每次pop或peek时,若输出栈为空则将输入栈的全部数据依次弹出并压入输出栈,这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序。

代码实现:
typedef int STDataType;
typedef struct Stack
{
  STDataType* a;
  int top;
  int capacity;
}ST;
void STInit(ST* pst)
{
  assert(pst);
  pst->a = NULL;
  pst->top = 0;
  pst->capacity = 0;
}
void STDestroy(ST* pst)
{
  assert(pst);
  free(pst->a);
  pst->a = NULL;
  pst->top = 0;
  pst->capacity = 0;
}
void STPush(ST* pst, STDataType x)
{
  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;
  pst->top++;
}
bool STEmpty(ST* pst)
{
  assert(pst);
  return pst->top == 0;
}
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];
}
int STSize(ST* pst)
{
  assert(pst);
  return pst->top;
}
//------以下为OJ提供-------
typedef struct {
  ST pushst;
  ST popst;
} MyQueue;
MyQueue* myQueueCreate() {
  MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
  if (obj == NULL) {
    perror("malloc fail");
    return 0;
  }
  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);
*/

复杂度分析

  • 时间复杂度:push和empty为O(1),pop和peek为均摊O(1)。对于每个元素,至多入栈和出栈各两次,故均摊复杂度为O(1)。
  • 空间复杂度:O(n)。其中n是操作总数。对于有n次push操作的情况,队列中会有n个元素,故空间复杂度为O(n)。

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
444 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
444 4
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
489 1
|
Python
【Leetcode刷题Python】50. Pow(x, n)
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
429 1
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
149 0
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
141 0
|
Python
【Leetcode刷题Python】1467. 两个盒子中球的颜色数相同的概率
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
312 0
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
235 6
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
339 4
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
538 2