leetcode 每日打卡 用兩個棧實現隊列

題目

用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 appendTail 和 deleteHead ,分別完成在隊列尾部插入整數和在隊列頭部刪除整數的功能。(若隊列中沒有元素,deleteHead 操作返回 -1 )
示例 1:

輸入:
[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[3],[],[]]
輸出:[null,null,3,-1]

示例 2:

輸入:
[“CQueue”,“deleteHead”,“appendTail”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[],[5],[2],[],[]]
輸出:[null,-1,null,null,5,2]

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof

分析

兩個棧模擬一個隊列,隊列是先進先出,而棧是先進後出。我們只需要兩個棧倒一手,即進棧A,然後在彈出到B。比如棧A分別進入1, 2, 3,在棧頂的是3。那麼倒一手到棧B,將分別把3, 2, 1進棧,此時棧B的棧頂是1。此時如果要出隊,就從B上出棧,這時候出的是1。是不是就實現了隊列先進先出了呢?

此題有個問題是,go語言並沒有提供棧這種內部實現,所以我們要採用slice來模擬棧,入棧就append,出棧就取末尾,實現先進後出,或者叫後進先出。

解法

type CQueue struct {
    s1 Stack
    s2 Stack
}

func Constructor() CQueue {
    return CQueue{}
}

func (this *CQueue) AppendTail(value int)  {
    this.s1.Push(value)
}

func (this *CQueue) DeleteHead() int {
    // 如果s2不爲空,那麼就直接pop就好了。
    // 把s1的都push到s2,然後從s2裏pop出來。
    if this.s2.Size() == 0 && this.s1.Size() > 0{
        for this.s1.Size() > 0 {
            this.s2.Push(this.s1.Pop())
        }
    }

    if this.s2.Size() > 0 {
        return this.s2.Pop()
    } else {
        return -1
    }
}


type Stack []int

func(s *Stack) Size() int {
    return len(*s)
}

// 以下棧的定義來自leetcode 題解中的一篇,其實就是用slice模擬棧,具體是哪位仁兄的忘記了。
func(s *Stack) Push(value int) {
    *s = append(*s, value)
}

func(s *Stack) Pop() int {
    n := len(*s)
    res := (*s)[n - 1]
    *s = (*s)[:n - 1]
    return res
}
/**
 * Your CQueue object will be instantiated and called as such:
 * obj := Constructor();
 * obj.AppendTail(value);
 * param_2 := obj.DeleteHead();
 */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章