1. 问题描述:
多级双向链表中,除了指向下一个节点和前一个节点指针之外,它还有一个子链表指针,可能指向单独的双向链表。这些子列表也可能会有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。给你位于列表第一级的头节点,请你扁平化列表,使所有结点出现在单级双链表中。
示例 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]
解释:输入的多级列表如下图所示:
扁平化后的链表如下图:
示例 2:
输入:head = [1,2,null,3]
输出:[1,3,2]
解释:
输入的多级列表如下图所示:
1---2---NULL
|
3---NULL
...
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list
2. 思路分析:
题目比较长表达的意思实际上类似于双链表在某个位置插入节点的过程,由题可知,子链表其实是一个递归定义的过程,所以我们使用递归解决即可,遍历当前链表,如果发现节点存在子链表那么就需要使用递归来将子链表处理完使其变成一个双链表的形式,因为我们需要在修改指针指向的时候需要用到子链表的头结点与尾节点,所以递归方法可以返回一个包含头结点与尾节点的列表,修改指针指向主要包括:将子链表的尾部接到当前节点的下一个节点的前面,当前节点的next指向子链表的头结点即可,当前节点的子链表清空,修改的时候是修改节点的双向联系,当前遍历的节点需要移动到下一个节点,并且需要将当前节点的子链表清空(看图修改指针的指针会更准确一点)。
3. 代码如下:
class Node:
def __init__(self, val, prev, next, child):
self.val = val
self.prev = prev
self.next = next
self.child = child
class Solution:
def dfs(self, root: "Node"):
if not root: return [None, None]
cur, tail = root, root
# 主要是修改指针指向
while cur:
tail = cur
# 当前节点有孩子节点的时候
if cur.child:
t = self.dfs(cur.child)
# 子链表的尾节点连接到当前节点的下一个节点前面
t[1].next = cur.next
# 下一个节点的pre指向子链表的尾节点
if cur.next: cur.next.prev = t[1]
# 当前节点的next指向子链表头结点
cur.next = t[0]
# 子链表pre指向当前节点
t[0].prev = cur
# 清空孩子节点
cur.child = None
# 移动当前指向的指针
cur = t[1].next
# 更新尾指针
tail = t[1]
else:
cur = cur.next
# 返回当前双链表的头结点与尾节点
return [root, tail]
def flatten(self, head: 'Node') -> 'Node':
return self.dfs(head)[0]