天天看點

吳師兄實名吐槽 LeetCode 上的一道題目。。。

吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。

今天分享的題目來源于 LeetCode 上的劍指 Offer 系列 面試題09. 用兩個棧實作隊列。

題目連結:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/

一、題目描述

用兩個棧實作一個隊列。隊列的聲明如下,請實作它的兩個函數 ​

​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]      

提示:

  • ​1 <= values <= 10000​

  • ​最多會對 appendTail、deleteHead 進行 10000 次調用​

二、題目解析

實名吐槽這道題目的示例描述,我第一次真的沒有看懂是啥意思。。。。

我用大白話來翻譯一下 示例 2。

["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
這個表示每一次操作的集合數組      
[[],[],[5],[2],[],[]]
這個表示每一次操作後對應的參數的集合數組      
吳師兄實名吐槽 LeetCode 上的一道題目。。。

1、CQueue

首先初始化,沒有參數,是以是  ​

​[]​

​​,然後我們注意到 ​

​CQueue()​

​ 函數是沒有傳回值的,用 null 來表示(不要問我為什麼用 null 表示。。。)

2、deleteHead

删除操作,沒有參數,是以是  ​

​[]​

​​,根據題意若隊列中沒有元素,​

​deleteHead​

​​ 操作傳回 ​

​-1​

​​ ,是以輸出值為 ​

​-1​

​ 。

3、appendTail

插入操作,有參數,此時是 5,并且 ​

​appendTail()​

​ 函數沒有傳回值的,用 null 來表示。

4、appendTail

插入操作,有參數,此時是 2,并且 ​

​appendTail()​

​ 函數沒有傳回值的,用 null 來表示。

5、deleteHead

删除操作,沒有參數,是以是  ​

​[]​

​,此時隊列中有元素,先進入的是 5,後進入的是 2,根據隊列 先進先出 的性質,元素 5 出列,是以傳回值是  5 。

6、deleteHead

删除操作,沒有參數,是以是  ​

​[]​

​,此時隊列中有元素,隻有元素 2,是以傳回值是  2 。

基本上看完上面的大白話翻譯就可以了解題意,解決問題也不難了。

入隊操作

如果是棧的插入操作,那我們可以把元素都先插入到 stack1 中,也就實作了隊列的 入隊操作 。

出隊操作

  • 當 stack2 中不為空時,直接操作,此時在 stack2 中的棧頂元素是最先進入隊列的元素,傳回該元素即可;
  • 如果 stack2 為空且 stack1 也為空,傳回 -1;
  • 如果 stack2 為空且 stack1 不為空,首先需要把 stack1 中的元素逐個彈出并壓入到 stack2 中,然後傳回  stack2 的棧頂元素即可。
吳師兄實名吐槽 LeetCode 上的一道題目。。。

示例

三、動畫描述

四、圖檔描述

吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。
吳師兄實名吐槽 LeetCode 上的一道題目。。。

五、參考代碼

class CQueue {

    LinkedList<Integer> stack1;
    LinkedList<Integer> stack2;

    public CQueue() {
        // 初始化 stack1 與 stack2
        stack1 = new LinkedList<Integer>();
        stack2 = new LinkedList<Integer>();
    }

    public void appendTail(int value) {
        // 直接将元素存放到 stack1 中
        stack1.addLast(value);
    }

    public int deleteHead() {
        // stack2 棧不為空,直接操作,傳回 stack2 的棧頂元素
        if(!stack2.isEmpty()) {
           return stack2.removeLast(); 
        }
        // 走到這一步的時候,stack2 是為空的狀态
        // 根據題意,當 stack1 為空時,直接傳回 -1
        if(stack1.isEmpty()){
            return -1;   
        }
        // 将 stack1 中的元素依次倒序放入 stack2 中
        while(!stack1.isEmpty()){
            stack2.addLast(stack1.removeLast()); 
        }
        // 傳回 stack2 的棧頂元素  
        return stack2.removeLast();
    }
}      

六、複雜度分析

插入元素操作

  • 時間複雜度:O(N)。插入元素時,對于已有元素,每個元素都要彈出棧兩次,壓入棧兩次,是以是線性時間複雜度。
  • 空間複雜度:O(N)。需要使用額外的空間存儲已有元素。

删除元素操作

  • 時間複雜度:O(1)。判斷元素個數和删除隊列頭部元素都使用常數時間。
  • 空間複雜度:O(1)。從第一個棧彈出一個元素,使用常數空間。

七、相關标簽

  • 隊列
由 五分鐘學算法 原班人馬打造的公衆号:圖解面試算法,現已正式上線!
接下來我們将會在該公衆号上,為大家分享優質的算法解題思路,堅持每天一篇原創文章的輸出,視訊動畫制作不易,感興趣的小夥伴可以關注點贊一下哈!      

繼續閱讀