持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天,点击查看活动详情
1、写在前面
大家好,我是翼同学,这里是【水滴计划 | 刷题日志】
每日两题,拒绝摆烂。
2、内容
2.1、题目一:用栈实现队列
(1) 描述
(2) 举例
(3) 解题
这道题要求我们使用栈结构来模拟队列的行为,考察我们对栈和队列的掌握程度。
如果单纯使用一个栈结构,不足以解决这道题,因此这里应该使用两个栈,分别是输入栈和输出栈。
具体的思路如下:
- 入队
push():当我们需要将元素x压入队列的末尾时,只需将元素压入输入栈即可; - 出队
pop():当我们需要移除队列的首元素时,则需判断输出栈是否为空?如果输出栈为空,则需要将输入栈的元素全部压入输出栈,再从输出栈弹出栈顶元素,此时就实现了出队操作。否则,如果输出栈不为空,则直接弹出输出栈的栈顶元素即可; - 返回队列首元素
peek():该函数的功能和pop()函数类似,稍微修改即可; - 判断队列是否为空
empty():如果输入栈和输出栈都为空,则证明该队列为空,返回ture;否则返回false。
class MyQueue {
public:
stack<int> StackIn; // 定义一个输入栈
stack<int> stackOut; // 定义一个输出栈
// 构造函数
MyQueue() {
// ...
}
// 入队
void push(int x) {
StackIn.push(x); // 将数据元素压入输入栈
}
// 弹出队列首元素
int pop() {
// 当输出栈为空时
if (stackOut.empty()) {
// 将输入栈中的全部元素压到输入栈中
while(!StackIn.empty()) {
// 将输入栈的栈顶元素压入输入栈中
stackOut.push(StackIn.top());
// 弹出输入栈的栈顶元素
StackIn.pop();
}
}
// pop()函数需要返回队列首元素,因此先用result暂存这个值
int result = stackOut.top();
// 弹出输出栈的栈顶元素
stackOut.pop();
// 返回队列的首元素
return result;
}
int peek() {
// 当输出栈为空时
if (stackOut.empty()) {
// 将输入栈中的全部元素压到输入栈中
while(!StackIn.empty()) {
// 将输入栈的栈顶元素压入输入栈中
stackOut.push(StackIn.top());
// 弹出输入栈的栈顶元素
StackIn.pop();
}
}
// 返回输出栈的栈顶元素
return stackOut.top();
}
bool empty() {
// 如果输入栈和输出栈都为空,则该模拟队列就为空
if(StackIn.empty() && stackOut.empty()) {
return true;
}
// 否则返回false
else {
return false;
}
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
2.2、题目二:用队列实现栈
(1) 描述
(2) 举例
(3) 解题
这道题要求我们利用队列来实现栈的特性。
前文我们利用了两个栈来模拟一个队列,而在这道题中,我们利用一个队列,其实就可以模拟栈了。由于队列中数据的存取规则是“先进先出”,此时将一个队列中的元素存入另一个队列,其实元素的顺序没有发生改变,也无法变成“先进后出”的栈存取规则。因此,如果仅利用一个队列结构来模拟栈结构时,在弹出栈顶元素时,只需将队列的队头元素添加到队尾,重复这个过程,直到遇到最后一个元素,就将该元素弹出即可实现栈的pop()函数。
class MyStack {
public:
queue<int> q; // 工作队列
MyStack() {
// ...
}
// 进栈操作
void push(int x) {
q.push(x);
}
// 弹出栈顶元素
int pop() {
// 将末尾元素之前的所有元素,按顺序添加到队列的尾部,并依次弹出
for(int i = 1; i < q.size(); i++) {
q.push(q.front());
q.pop();
}
// 经过 for 循环后,队列首元素已变成了之前的队尾元素
// 这样就实现了栈的 “后进先出” 规则,此时弹出的队头元素就是按照栈的顺序弹出的
int top = q.front();
q.pop();
return top;
}
// 返回栈顶元素,调用 back() 函数即可
int top() {
return q.back();
}
// 判断栈是否为空,调用 empty() 即可
bool empty() {
return q.empty();
}
};
3、写在最后
好了,今天就刷到这里,明天再来。