你会得到一个双链表,其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针
。这个子指针可能指向一个单独的双向链表,也包含这些特殊的节点。这些子列表可以有一个或多个自己的子列表,以此类推,以生成如下面的示例所示的
多层数据结构 。
给定链表的头节点 head ,将链表 扁平化 ,以便所有节点都出现在单层双链表中。让 curr
是一个带有子列表的节点。子列表中的节点应该出现在
扁平化列表 中的 curr
之后 和 curr.next
之前 。
返回 扁平列表的head
。列表中的节点必须将其 所有 子指针设置为 null
。
示例 1:
**输入:** head = [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]
**输出:** [1,2,3,7,8,11,12,9,10,4,5,6]
**解释:** 输入的多级列表如上图所示。
扁平化后的链表如下图:
![](https://assets.leetcode.com/uploads/2021/11/09/flatten12.jpg)
示例 2:
**输入:** head = [1,2,null,3]
**输出:** [1,3,2]
**解释:** 输入的多级列表如上图所示。
扁平化后的链表如下图:
![](https://assets.leetcode.com/uploads/2021/11/24/list.jpg)
示例 3:
**输入:** head = []
**输出:** []
**说明:** 输入中可能存在空列表。
提示:
- 节点数目不超过
1000
1 <= Node.val <= 105
如何表示测试用例中的多级链表?
以 示例 1 为例:
1---2---3---4---5---6--NULL
|
7---8---9---10--NULL
|
11--12--NULL
序列化其中的每一级之后:
[1,2,3,4,5,6,null]
[7,8,9,10,null]
[11,12,null]
为了将每一级都序列化到一起,我们需要每一级中添加值为 null 的元素,以表示没有节点连接到上一级的上级节点。
[1,2,3,4,5,6,null]
[null,null,7,8,9,10,null]
[null,11,12,null]
合并所有序列化结果,并去除末尾的 null 。
[1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]
方法一:深度优先搜索
思路与算法
当我们遍历到某个节点 node 时,如果它的 child 成员不为空,那么我们需要将 child 指向的链表结构进行扁平化,并且插入 node 与 node 的下一个节点之间。
因此,我们在遇到 child 成员不为空的节点时,就要先去处理 child 指向的链表结构,这就是一个「深度优先搜索」的过程。当我们完成了对 child 指向的链表结构的扁平化之后,就可以「回溯」到 node 节点。
为了能够将扁平化的链表插入 node 与 node 的下一个节点之间,我们需要知道扁平化的链表的最后一个节点 last,随后进行如下的三步操作:
这样一来,我们就可以将扁平化的链表成功地插入。
在深度优先搜索完成后,我们返回给定的首节点即可。
细节
需要注意的是,node 可能没有下一个节点,即 next 为空。此时,我们只需进行第二步操作。
此外,在插入扁平化的链表后,我们需要将 node 的 child 成员置为空。
代码
[sol1-C++]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class Solution { public: Node* flatten(Node* head) { function<Node*(Node*)> dfs = [&](Node* node) { Node* cur = node; Node* last = nullptr;
while (cur) { Node* next = cur->next; if (cur->child) { Node* child_last = dfs(cur->child);
next = cur->next; cur->next = cur->child; cur->child->prev = cur;
if (next) { child_last->next = next; next->prev = child_last; }
cur->child = nullptr; last = child_last; } else { last = cur; } cur = next; } return last; };
dfs(head); return head; } };
|
[sol1-Java]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class Solution { public Node flatten(Node head) { dfs(head); return head; }
public Node dfs(Node node) { Node cur = node; Node last = null;
while (cur != null) { Node next = cur.next; if (cur.child != null) { Node childLast = dfs(cur.child);
next = cur.next; cur.next = cur.child; cur.child.prev = cur;
if (next != null) { childLast.next = next; next.prev = childLast; }
cur.child = null; last = childLast; } else { last = cur; } cur = next; } return last; } }
|
[sol1-C#]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public class Solution { public Node Flatten(Node head) { DFS(head); return head; }
public Node DFS(Node node) { Node cur = node; Node last = null;
while (cur != null) { Node next = cur.next; if (cur.child != null) { Node childLast = DFS(cur.child);
next = cur.next; cur.next = cur.child; cur.child.prev = cur;
if (next != null) { childLast.next = next; next.prev = childLast; }
cur.child = null; last = childLast; } else { last = cur; } cur = next; } return last; } }
|
[sol1-Python3]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class Solution: def flatten(self, head: "Node") -> "Node": def dfs(node: "Node") -> "Node": cur = node last = None
while cur: nxt = cur.next if cur.child: child_last = dfs(cur.child) nxt = cur.next cur.next = cur.child cur.child.prev = cur
if nxt: child_last.next = nxt nxt.prev = child_last
cur.child = None last = child_last else: last = cur cur = nxt
return last
dfs(head) return head
|
[sol1-JavaScript]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| var flatten = function(head) { const dfs = (node) => { let cur = node; let last = null;
while (cur) { let next = cur.next; if (cur.child) { const childLast = dfs(cur.child);
next = cur.next; cur.next = cur.child; cur.child.prev = cur;
if (next != null) { childLast.next = next; next.prev = childLast; }
cur.child = null; last = childLast; } else { last = cur; } cur = next;
} return last; }
dfs(head); return head; };
|
[sol1-Golang]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| func dfs(node *Node) (last *Node) { cur := node for cur != nil { next := cur.Next if cur.Child != nil { childLast := dfs(cur.Child)
next = cur.Next cur.Next = cur.Child cur.Child.Prev = cur
if next != nil { childLast.Next = next next.Prev = childLast }
cur.Child = nil last = childLast } else { last = cur } cur = next } return }
func flatten(root *Node) *Node { dfs(root) return root }
|
复杂度分析