算法修煉之路——【鏈表】Leetcode 430 扁平化多級雙向鏈表

題目描述

多級雙向鏈表中,除了指向下一個節點和前一個接待你指針之外,它還有一個子鏈表指針,可能指向單獨的雙向鏈表。這些子鏈表也可能會有一個或多個自己的子項,依此類推,生成多級數據結構,如下面的示例所示。

給你位於列表第一級的頭節點,請你扁平化列表,使所有節點出現在單極雙鏈表中。

示例1:

輸入: head = [1, 2, 3, 4, 5, 6, null, null, null, 7, 8, 9, 10, null, null, 11, 12]
輸出: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
解釋
在這裏插入圖片描述
** 圖1**

示例2:

輸入: head = []
輸出: []

說明:

  • 節點數目不超過1000
  • 1 <= node.val < 10E5

思路分析

我們看到題幹首先想到的是,深度優先搜索算法,所以我們直接藉助stack保存具有child非空指針後的節點,當深度遍歷完之後,從stack中彈出保存點,接着遍歷。

在這裏插入圖片描述
圖2

我們通過圖2可知,設遍歷指針爲curr,紅色箭頭爲curr的遍歷軌跡:

  1. 當存在child節點時,將curr.next壓入棧中,直接遍歷curr.child
  2. 當在下沉過程中,又檢測到child節點,則重複步驟1
  3. 在最後一級鏈表到盡頭時,檢測棧是否爲空:不爲空則彈出棧頂元素(返回上一級鏈表);爲空則完成多級鏈表的遍歷,直接輸出結果output.

解題步驟

  1. 初始化兩個分區指針oddTail, evenTail和布爾變量isOddNode
  2. 遍歷原始鏈表,根據isOddNode判斷evenTail.next是否插入奇數分區;
  3. evenTail.next == null時停止並返回head.

解題代碼

    public static ListNode solution(ListNode head) {
        if (head == null) {
            return head;
        }

        /* Step1: Init. pointers */
        Stack<ListNode> stack = new Stack<>();
        ListNode curr = head;

        /* Step2: go through the head-list
        and
        go back last level when no more subsequent child and next nodes
         */
        while (curr != null) {
            // exists child-node
            if (curr.child != null) {
                ListNode node = curr.next;
                stack.push(node);

                curr.next = curr.child;
            }

            // back to last level
            if (curr.next == null && !stack.isEmpty()) {
                curr.next = stack.peek();
                curr = stack.pop();
            }

            curr = curr == null ? null : curr.next;
        }
        /* Step3: return head */
        return head;
    }

複雜度分析

時間複雜度:我們對原始鏈表進行了一次遍歷,容易理解時間複雜度爲O(N);
空間複雜度:我們這裏設置了輔助容器stack,故空間複雜度爲O(N).

GitHub源碼

完整可運行文件請訪問GitHub

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