記事ディレクトリ
キューを使用したスタックの実装
このセクションは「Code Random Notes: Code Random Notes」に対応しており、対応するビデオ リンクは「Basic Operations of Queues!」です。| LeetCode: 225. キューを使用して stack_bilibili_bilibili を実装する
エクササイズ
質問リンク: 225. キューを使用してスタックを実装する - LeetCode
後入れ先出し (LIFO) スタックを実装し、通常のスタックの 4 つの操作 (プッシュ、トップ、ポップ、空) をすべてサポートするには、2 つのキューのみを使用してください。
MyStack クラスを実装します。
- void Push(int x) 要素 x をスタックの先頭にプッシュします。
- int Pop() はスタックの最上位要素を削除して返します。
- int top() はスタックの最上位の要素を返します。
- boolean empty() スタックが空の場合は true を返し、それ以外の場合は false を返します。
上級: キューだけでスタックを実装できますか。
2つのキュー
キューは先入れ先出しであることがわかっています。たとえば、入場順序が 1 2 3 の場合、外に出るときも 1 2 3 になります。スタックから出る順序は 3 2 1 と逆になります。
直観的に、スタックは 2 つのキューを使用して実装できます。キューから出されるのは最初の要素であり、スタックから出されるのは最後の要素です。次に、最初に要素を 2 番目のキューにプッシュし、次に最初のキュー内のすべての要素をキュー 2 にプッシュできます。このようにして、新しく入ってくる要素は毎回キューの先頭に配置され、ポップするときに、最後に入ってくる要素を直接ポップすることができます。最後に、キュー 1 とキュー 2 が交換され、キュー 1 にはすべての要素が保存され、キュー 2 にはプッシュ中に要素が一時的に保存されるだけになります。
上記の考え方は LeetCode の公式ソリューションであり、プッシュする場合は 2 番目のキューを使用し、
コードをポップする場合は 2 番目のキューを使用するが、どちらの方法でも実装できます。
class MyStack {
private:
queue<int> q1;
queue<int> q2;
public:
MyStack() {
}
void push(int x) {
// 先将元素放入q2
q2.push(x);
// 把q1的元素都移到q2里面
while (!q1.empty()) {
q2.push(q1.front());
q1.pop();
}
// 交换q1和q2,这样新进来的元素就在q1的开头位置
swap(q1, q2);
}
int pop() {
int res = q1.front();
q1.pop();
return res;
}
int top() {
return q1.front(); }
bool empty() {
return q1.empty(); }
};
- 時間計算量: プッシュは O( nnn )、残りは O(1) です。ここで、n はスタック内の要素の数です
- 空間複雑さ: O( nnn )。要素をスタックに格納するには 2 つのキューを使用する必要があります。n はスタック内の要素の数です。
キュー
上記で使用した 2 つのキューは主に、キュー内の最後の要素をどのようにポップアウトするかという問題を解決し、2 番目のキューは要素を一時的に格納する場所として使用されます。
要素をプッシュした後、プッシュする前のすべての要素を順番にポップし、再度キューにプッシュします。元のキューが 3 2 1 の場合、要素 4 がプッシュされます。プッシュ後は 3 2 1 4 となり、元の 3 つの要素が次々にポップされてプッシュされ、4 3 2 1 になります。このようにして、新たに入力された要素 4 がキューのリーダーとなり、スタックの後入れ先出し機能が実現されます。上記の解決策とプッシュ時の動作のみが異なります。
class MyStack {
private:
queue<int> q1;
public:
MyStack() {
}
void push(int x) {
int size = q1.size();
q1.push(x);
for (int i = 0; i < size; i++)
{
q1.push(q1.front());
q1.pop();
}
}
int pop() {
int res = q1.front();
q1.pop();
return res;
}
int top() {
return q1.front(); }
bool empty() {
return q1.empty(); }
};
- 時間計算量: プッシュは O( nnn )、残りは O(1) です。ここで、n はスタック内の要素の数です
- 空間複雑さ: O( nnn )。要素をスタックに格納するにはキューを使用する必要があります。n はスタック内の要素の数です。