【LeetCode 225】用一個or兩個隊列實現棧

LeetCode 225:

Implement the following operations of a stack using queues.
push(x) – Push element x onto stack.
pop() – Removes the element on top of the stack.
top() – Get the top element.
empty() – Return whether the stack is empty.

要用隊列實現堆棧,主要就是要實現上述的四個功能函數,這裏給出兩種解法,第一種是利用兩個隊列來實現棧的解法:

class MyStack {

    Queue<Integer> queue1;
    Queue<Integer> queue2;

    /** Initialize your data structure here. */
    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }

    /** Push element x onto stack. */
    public void push(int x) {
        if (this.empty()) {
            queue1.add(x);
        } else {
            if (queue1.isEmpty()) {
                queue2.add(x);
            } else {
                queue1.add(x);
            }
        }
    }

    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        int value = 0;
        if (queue1.isEmpty()) {
            while (queue2.size() > 1) {
                queue1.add(queue2.poll());
            }
            value = queue2.poll();
        } else {
            while (queue1.size() > 1) {
                queue2.add(queue1.poll());
            }
            value = queue1.poll();
        }
        return value;
    }

    /** Get the top element. */
    public int top() {
        int value = 0;
        if (queue1.isEmpty()) {
            while (queue2.size() > 1) {
                queue1.add(queue2.poll());
            }
            value = queue2.peek();
            queue1.add(queue2.poll());
        } else {
            while (queue1.size() > 1) {
                queue2.add(queue1.poll());
            }
            value = queue1.peek();
            queue2.add(queue1.poll());
        }
        return value;
    }

    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

它的思路就是:當你要取一個元素時,相當於要取隊列的最末一個元素,將隊列前n - 1個元素都移動到另外一個隊列中,剩下的,就是原隊列中的最末一個元素,取出即使棧返回的結果。這種思路非常好,但代碼可能不太簡潔。

第二種,是隻用一個隊列的解法,稍微難想一點,但更簡潔:

class MyStack {

    Queue<Integer> queue;

    /** Initialize your data structure here. */
    public MyStack() {
        queue = new LinkedList<>();
    }

    /** Push element x onto stack. */
    public void push(int x) {
        queue.add(x);
        for (int i = 0; i < queue.size() - 1; i++) {
            queue.add(queue.poll());
        }
    }

    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return queue.poll();
    }

    /** Get the top element. */
    public int top() {
        return queue.peek();
    }

    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue.isEmpty();
    }
}

這段代碼主要可能出現的疑惑在於,壓入棧的部分,只要這一部分想通了,後面的部分就容易考慮了。

我們可以這麼想,隊列的特點是什麼?一邊入一邊出,先入先出,而棧是先入後出,那,我們是否可以通過某些方法,讓隊列的一端維持“棧”的那種先入後出的狀態呢?
我們可以想,如果對於兩個元素:a、b,出的順利應該爲: b、a,對於三個元素,a、b、c,出棧的順利應該爲 c、b、a,從兩個元素,到三個元素,我們壓入了一個元素c,而我們應該維護的順序,從"b、a",變成了壓棧後"b、a、c",變成"c、b、a",可以發現,對於每進入一個元素,將前面所有元素取出再重新入隊列,可以維護同棧一樣的順序,因此:

    public void push(int x) {
    	// 加入一個元素
        queue.add(x);
        // 在這個元素前的所有元素進行出隊列,再入隊列的操作
        for (int i = 0; i < queue.size() - 1; i++) {
            queue.add(queue.poll());
        }
    }

在LeetCode上進行執行,都可以通過:
在這裏插入圖片描述
用兩個隊列的方法更快一些,但同時佔用內存的量更大。

其他 LeetCode JAVA代碼:
https://github.com/Parallelline1996/LeetCode/tree/master

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章