1. 程式人生 > >Leetcode __232. 用棧實現佇列

Leetcode __232. 用棧實現佇列

問題描述

使用棧實現佇列的下列操作:

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 操作)。

解題思路

實現

stackSave:取,查,彈出
stackHelper:存

class MyQueue {
    private Stack<Integer> stackSave;//儲存佇列
    private Stack<Integer> stackHelper;//輔助

    /** Initialize your data structure here. */
    public MyQueue() {
        stackSave = new Stack<Integer>();
        stackHelper = new Stack<Integer>();
    }

    /** Push element x to the back of queue. */
    public void push(int x) {//在push的時候就把順序調整好,始終取值的時候都要從stackSave中取
        while (!stackSave.empty()) {
            stackHelper.push(stackSave.pop());
        }
        stackSave.push(x);
        while (!stackHelper.empty()){
            stackSave.push(stackHelper.pop());
        }
    }

    /** Removes the element from in front of queue and returns that element. */
    public int pop() {//從stackSave中彈出即可,在push的時候,已經將最終的順序調整好了
        return  stackSave.pop();
    }

    /** Get the front element. */
    public int peek() {//從stackSave中,檢視最棧頂元素即可,就是隊首元素,因為在push的時候隊首隊尾已經調整好順序
        return stackSave.peek();
    }

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

another

要始終保持一個stack為空

class MyQueue {
    private Stack<Integer> stackSave;//
    private Stack<Integer> stackHelper;//

    /** Initialize your data structure here. */
    public MyQueue() {
        stackSave = new Stack<Integer>();
        stackHelper = new Stack<Integer>();
    }

    /** Push element x to the back of queue. */
    public void push(int x) {//所有的存操作都在stackHelper中,存的時候就把另一個stack倒入到stackHelper中,再操作
        action(stackSave, stackHelper);
        stackHelper.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    public int pop() {//所有的取。彈出都要從stacksave中取,所以第一步要講stackHelper棧的元素都倒入stacksave中,然後再彈出
        action(stackHelper, stackSave);
        return  stackSave.pop();
    }

    /** Get the front element. */
    public int peek() {//所有的取,查,彈出都要從stacksave中取,所以第一步要講stackHelper棧的元素都倒入stacksave中,然後再查
        action(stackHelper, stackSave);
        return stackSave.peek();
    }

    /** Returns whether the queue is empty. */
    public boolean empty() {//這時,資料可能都在stackHelper中,也有可能都在stackSave中,要判斷一下
        return (stackHelper.empty() && stackSave.empty());
    }

    private void action(Stack<Integer> source, Stack<Integer> dest) {
        while (!source.empty()){
            dest.push(source.pop());
        }
    }
}

another

這裡屬於優化,減少導換stack的次數

class MyQueue {
    Stack<Integer> in = null;
    Stack<Integer> out = null; 
    public MyQueue() {
        in = new Stack<>();
        out = new Stack<>();
    }
    public void push(int x) {
        in.push(x);
    }
    public int pop() {
        peek();
        return out.pop();
    }
    public int peek() {//不空的時候,直接查詢返回即可
        if(out.isEmpty())//空的時候,再倒換stack
            while(!in.isEmpty())
                out.push(in.pop());
        return out.peek();
    }
    public boolean empty() {
        return in.isEmpty() && out.isEmpty();
    }
}

知識點

Java Stack 類
棧是Vector的一個子類,它實現了一個標準的後進先出的棧。

堆疊只定義了預設建構函式,用來建立一個空棧。 堆疊除了包括由Vector定義的所有方法,也定義了自己的一些方法。

Stack()
除了由Vector定義的所有方法,自己也定義了一些方法:

序號 方法描述
1 boolean empty() 測試堆疊是否為空。
2 Object peek( ) 檢視堆疊頂部的物件,但不從堆疊中移除它。
3 Object pop( ) 移除堆疊頂部的物件,並作為此函式的值返回該物件。
4 Object push(Object element) 把項壓入堆疊頂部。
5 int search(Object element) 返回物件在堆疊中的位置,以 1 為基數。