您將得到一個雙向鏈表,除了下一個和前一個指針以外,它還有一個子指針,可能指向單獨的雙向鏈表。這些子列表可能有一個或多個本身的子項,依此類推,生成多級數據結構,以下面的示例所示。node
扁平化列表,使全部結點出如今單級雙鏈表中。您將得到列表第一級的頭部。數據結構
You are given a doubly linked list which in addition to the next and previous pointers, it could have a child pointer, which may or may not point to a separate doubly linked list. These child lists may have one or more children of their own, and so on, to produce a multilevel data structure, as shown in the example below.app
Flatten the list so that all the nodes appear in a single-level, doubly linked list. You are given the head of the first level of the list.函數
示例:指針
輸入: 1---2---3---4---5---6--NULL | 7---8---9---10--NULL | 11--12--NULL 輸出: 1-2-3-7-8-11-12-9-10-4-5-6-NULL
以上示例的說明:code
給出如下多級雙向鏈表:blog
咱們應該返回以下所示的扁平雙向鏈表:遞歸
這道題是典型的 DFS(深度優先搜索)型例題,而且給出了圖解,只要瞭解過 DFS 的應該當即就能想到思路。it
針對這道題簡單說下:深度優先搜索 就像一棵樹(二叉樹)的前序遍歷,從某個頂點(鏈表頭節點)出發,自頂向下遍歷,而後遇到頂點的未被訪問的鄰接點(子節點 Child),繼續進行深度優先遍歷,重複上述過程(遞歸),直到全部頂點都被訪問爲止。io
其邏輯以示例輸入爲例:
1---2---3---4---5---6--NULL | 7---8---9---10--NULL | 11---12---NULL
從節點 1 開始遍歷,當前遍歷鏈表爲:1---2---3---4---5---6--NULL 遇到鄰接點 2,其子鏈表爲:7---8---9---10--NULL 將子鏈表頭節點 7 做爲參數傳入 DFS 函數,當前遍歷鏈表爲:7---8---9---10---NULL 繼續遍歷,遇到鄰接點 8,其子鏈表爲:11--12--NULL 將子鏈表頭節點 8 做爲參數傳入 DFS 函數,當前遍歷鏈表爲:11--12---NULL 繼續遍歷,無鄰接點,遍歷結束,返回當前鏈表尾節點 12 改變鄰接點 8 與子鏈表頭節點 11 關係:7---8---11---12 鏈接返回值 尾節點 12 和鄰接點的下一個節點 9: 7---8---11---12---9---10---NULL 繼續遍歷,無鄰接點,遍歷結束,返回當前鏈表尾節點 10 改變鄰接點 2 與 子鏈表頭節點 7 關係:1---2---7---8---11---12---9---10--NULL 鏈接返回值 尾節點 10 和鄰接點的下一個節點 3: 1---2---7---8---11---12---9---10---3---4---5---6--NULL 繼續遍歷,無鄰接點,遍歷結束,返回當前鏈表尾節點 6 遞歸結束,返回頭節點 1,鏈表爲: 1---2---7---8---11---12---9---10---3---4---5---6--NULL
Java:
class Solution { public Node flatten(Node head) { dfs(head); return head; } //深度優先搜索函數 private Node dfs(Node head) { Node cur = head; while (cur != null) { if (cur.child != null) { //改變當前節點與子節點的關係 Node next = cur.next;//記錄暫存下一個節點 cur.next = cur.child;//當前節點與子鏈表頭節點鏈接 cur.next.prev = cur; //傳遞子鏈表頭節點做爲參數到 dfs Node childLast = dfs(cur.child);//childLast得到返回值爲子鏈表的尾節點 childLast.next = next;//子鏈表尾節點與暫存節點鏈接 if (next != null) next.prev = childLast;//暫存節點不爲空就將其prev指向子鏈表尾節點 cur.child = null;//子鏈表置空 cur = childLast;//刷新當前節點,跳過子鏈表的遍歷 } head = cur;//頭節點刷新爲當前節點 cur = cur.next;//刷新當前節點 } return head;//返回子鏈表的尾節點 } }
Python3:
class Solution: def flatten(self, head: 'Node') -> 'Node': self.dfs(head) return head def dfs(self, head): cur = head while cur: if cur.child: next = cur.next cur.next = cur.child cur.next.prev = cur childLast = self.dfs(cur.child) childLast.next = next if next: next.prev = childLast cur.child = None head = cur cur = cur.next return head
歡迎關注微.信公.衆號:愛寫Bug