问题描述:
您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表。这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。
扁平化列表,使所有结点出现在单级双链表中。您将获得列表第一级的头部。
示例:
输入: 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
以上示例的说明:
给出以下多级双向链表:
我们应该返回如下所示的扁平双向链表:
基本思路:
- 简单来说就是利用递归把相关的双链表插入到原来的节点之后。这样一说就特别明了了。
- 插入双链表和插入一个节点唯一的区别就在于——插入双链表还要通过循环获得其尾节点。
- 注意如果是在双链表的末尾插入相关链表的时候,后面节点(因为是NULL)prev指针就不需要重新指了。
AC代码:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* prev;
Node* next;
Node* child;
Node() {}
Node(int _val, Node* _prev, Node* _next, Node* _child) {
val = _val;
prev = _prev;
next = _next;
child = _child;
}
};
*/
class Solution {
public:
Node *result; // 类里设置成员变量,等价于设置成员变量
Node* flatten(Node* head) {
// 处理特殊情况
if (!head) return NULL;
auto p = head; // 追踪每个节点
while (p) {
// 如果有孩子节点,递归完成
if (p->child) {
auto insert = flatten(p->child); // 获得待插入的链表
p->child = NULL;
// temp是前一个节点,p是后一个节点
Node *temp = p;
p = p->next;
// 链接前面
temp->next = insert;
insert->prev = temp;
// 获得末尾节点
while (insert->next){
insert = insert->next;
}
insert->next = p;
if (p) p->prev = insert; // 对于双链表插入一个节点的易错点
} else {
p = p->next;
}
}
return head;
}
};