一、題目
使用棧實現隊列的下列操作:
- push(x) -- 將一個元素放入隊列的尾部。
- pop() -- 從隊列首部移除元素。
- peek() -- 返回隊列首部的元素。
- empty() -- 返回隊列是否爲空。
示例:
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false
說明:
- 你只能使用標準的棧操作 -- 也就是隻有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
- 你所使用的語言也許不支持棧。你可以使用 list 或者 deque(雙端隊列)來模擬一個棧,只要是標準的棧操作即可。
- 假設所有操作都是有效的 (例如,一個空的隊列不會調用 pop 或者 peek 操作)。
二、題解
- 解法1:兩個棧
隊列是先進先出,棧是先進後出。所以可以用兩個棧,新元素壓入棧的時候,先將棧中的元素彈出,放到另一個棧中,把新元素壓入到棧的底部,再把另一個棧的元素彈出,放回原棧中。此時,棧頂元素就是出隊時要先出的隊首元素。
這裏用的是數組表示隊列,空間複雜度O(n),時間複雜度分 push 和 pop ,前者是O(n),後者是O(1)。
class MyQueue {
/**
* Initialize your data structure here.
*/
function __construct() {
$this->stack1 = [];
$this->stack2 = [];
}
/**
* Push element x to the back of queue.
* @param Integer $x
* @return NULL
*/
function push($x) {
while (!$this->empty()) {
$this->stack2[] = array_pop($this->stack1);
}
$this->stack1[] = $x;
while (!empty($this->stack2)) {
$this->stack1[] = array_pop($this->stack2);
}
}
/**
* Removes the element from in front of queue and returns that element.
* @return Integer
*/
function pop() {
return array_pop($this->stack1);
}
/**
* Get the front element.
* @return Integer
*/
function peek() {
return end($this->stack1);
}
/**
* Returns whether the queue is empty.
* @return Boolean
*/
function empty() {
return empty($this->stack1) ? true :false;
}
}
- 解法2:兩個棧
使用兩個棧,一個棧(stack1)僅負責入棧,一個棧(stack2)僅負責出棧。有新元素入隊時,直接將元素壓入 stack1 即可。但當出隊時,需要判斷 stack2 是否爲空,如果爲空,將 stack1 的元素依次出棧,壓入 stack2 中,隨後從 stack2 彈出,即爲出隊。但當 stack2 不爲空時,仍然直接從 stack2 出棧即可,知道 stack2 爲空時,纔可將 stack1 的元素拿出來放入 stack2 中。
這裏用的是數組表示隊列,空間複雜度O(n),時間複雜度分 push 和 pop ,前者是O(n),後者是O(1)。
class MyQueue2 {
/**
* Initialize your data structure here.
*/
function __construct() {
$this->stack1 = [];
$this->stack2 = [];
}
/**
* Push element x to the back of queue.
* @param Integer $x
* @return NULL
*/
function push($x) {
$this->stack1[] = $x;
}
/**
* Removes the element from in front of queue and returns that element.
* @return Integer
*/
function pop() {
if (empty($this->stack2)) {
while (!empty($this->stack1)) {
$this->stack2[] = array_pop($this->stack1);
}
}
return array_pop($this->stack2);
}
/**
* Get the front element.
* @return Integer
*/
function peek() {
if (empty($this->stack2)) {
while (!empty($this->stack1)) {
$this->stack2[] = array_pop($this->stack1);
}
}
return end($this->stack2);
}
/**
* Returns whether the queue is empty.
* @return Boolean
*/
function empty() {
return empty($this->stack1) && empty($this->stack2) ? true : false;
}
}