232. Implement Queue using Stacks
使用栈实现队列的下列操作:
push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
1. 第一个回合 题目理解 必须满足队列的 FIFO特征
我想到以前做个类似选择题,,但是忘记了 ,忘记里面关键地方是什么?
思路中断
image.png后记:
寻找的找个题目,
假设栈的输入序列为1、2、3、...、n,设计算法求出所有可能的出栈序列(合法序列)。
比如 n = 4,出栈序列可能有1 2 3 4 , 1 2 4 3 , 1 4 3 2 , 1 3 4 2等等
关键点
来了一批数据,入栈n个元素,可能有1--n个出栈方式
来了一批数据,入栈m个元素,可能有1--m个出栈方式
序列1、2、3、...、n 可以拆分不同的序列
2. 第二次尝试 用2个stack来模拟队列的基本操作
入队列,和出队列,第一个存储,第二个输入出
但是情况
输入序列: 1 2 3 4 5,
第一次:1 2 3 入栈 12 出栈
第二次:4 5 入栈 3怎么出栈?
这是很明显了,在第二次入栈之前,必须stack2数据完全出栈,但是用户可能不按照你操作来。思路中断,无法进行下去了。
你假设 stack2 回到stack1这个点,你想到了,但是无法作为算法进行描述
后记:
image.png
3. 第三次尝试
队列入栈
- 如果stack2 为null ,直接入栈stack1
2 如果stack2 不会空,说明,第一次插入,还有数据,需要倒回。
code
/**
执行用时: 28 ms, 在Implement Queue using Stacks的C++提交中击败了
9.45% 的用户
push time:o(n)
pop time: o(n)
**/
class MyQueue {
public:
/** Initialize your data structure here. */
MyQueue() {
m_total =0;
}
/** Push element x to the back of queue. */
void push(int x) {
m_total++;
//
if(!m_output.empty()){
while(!m_output.empty()){
m_input.push(m_output.top());
m_output.pop();
}
}
m_input.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
m_total--;
int val=peek();
m_output.pop();
return val;
}
/** Get the front element. */
int peek() {
//序列:第一个入队列的,需要第一个出队列
if (m_output.empty())
{
if(m_output.empty()){
while(!m_input.empty()){
m_output.push(m_input.top());
m_input.pop();
}
}
}
return m_output.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return m_total ==0;
}
private:
stack<int> m_input; //入队列操作
stack<int> m_output;//出队列操作
int m_total;
};
优化 pop o(n)-o(1),但是push 可能比较繁琐,不适合频繁插入
/**
time:
push o(n)
pop o(1)
执行用时: 0 ms, 在Implement Queue using Stacks的C++提交中击败了100.00% 的用户
**/
class MyQueue {
public:
/** Initialize your data structure here. */
MyQueue() {
m_total =0;
}
/** Push element x to the back of queue. */
void push(int x) {
m_total++;
//
if(!m_output.empty()){
while(!m_output.empty()){
m_input.push(m_output.top());
m_output.pop();
}
}
m_input.push(x);
while(!m_input.empty())
{
m_output.push(m_input.top());
m_input.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
m_total--;
int val=peek();
m_output.pop();
return val;
}
/** Get the front element. */
int peek() {
//序列:第一个入队列的,需要第一个出队列
return m_output.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return m_total ==0;
}
private:
stack<int> m_input; //入队列操作
stack<int> m_output;//出队列操作
int m_total; //记录大小
};
测试
- test 1
序列 A B C| D
入队列 A B C. 出队列 A B ,
在入队列 D.
------2018/12/23
网友评论