你会得到一个双链表,其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针 。这个子指针可能指向一个单独的双向链表,也包含这些特殊的节点。这些子列表可以有一个或多个自己的子列表,以此类推,以生成如下面的示例所示的 多层数据结构 。
给定链表的头节点 head ,将链表 扁平化 ,以便所有节点都出现在单层双链表中。让 curr 是一个带有子列表的节点。子列表中的节点应该出现在扁平化列表中的 curr 之后 和 curr.next 之前 。
返回 扁平列表的 head 。列表中的节点必须将其 所有 子指针设置为 null 。
输入:head = []
输出:[]
说明:输入中可能存在空列表。
如何表示测试用例中的多级链表?
以 示例 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]
#include<vector>
#include<algorithm>
class Solution {
public:
Node* flatten(Node* head) {
vector<Node*> a;
a.push_back(NULL); //(1)
Node* now = head;
while(now){ //(2)
if(now->child != NULL){
a.push_back(now->next); //将跳过的节点储存在a中
now->next = now->child; //深度优先
now->child = NULL;
now->next->prev = now; //改前驱
}
now = now->next; //不断向后遍历
}
int len = a.size()-1; //(3)
now = head;
while(len){
if(now->next == NULL){ //到达一行中最后一个节点时
while(a[len] == NULL && len > 0){
len--; //中间如果有空指针,就跳过
}
if(len == 0){
break; //遍历到最后一行就跳出循环
}
now->next = a[len]; //改后继,改成上一次跳过的位置
a[len]->prev = now; //后继的前驱就是now本身
len--;
}
now = now->next;
}
return head;
}
};
解题思路:
(1)建立一个结构体指针的数组vector<Node*> a。
- a.push_back()在后面添加元素;a.size()获得a的长度。
- 我的想法就是在一遍普通的遍历中,不断调整指针的指向,来达到我最终的目的。
(2)链表元素是分层的,而且层与层直接只有一个链接点,
- 如果我在遍历的过程中找到了这个链接点child,就跳过该层后面的元素,
- 把自己的下一个指针next改成child。
- 并且记录我从哪里开始跳过的。
- 这次的while循环目的主要是建立好我的a数组,找出每层在哪个位置跳过。顺便把child这条线给“拉直了”。
(3)len代表层数,代表我跳过了几次,我在0号位置加了空指针,
- a[len]代表我最近一次的跳过的位置。
- len递减,在len == 0 的时候,说明所有元素都访问了。
- 如果中间有其他元素是空指针,我的指向就应该是上上层跳过的位置,所以加入了一个while循环跳过空指针。