我的方法是用DFS 一开始想直接在head链表的基础上进行修改
结果发现单纯的dfs不行,因为当遍历的有子节点的结点时可以改变这两个结点间的链接关系,但是当一个分支全部遍历完毕之后,还要回到上一级,就是上个有孩子结点的那个结点的后一个结点,所以就需要把这些需要结点都要保存下来,有2个结点就要保存2个,有100个结点就要保存100个但从传递参数的角度来看,是不现实的。理论上可以传递一个栈的指针,用栈来保存这些结点,但一个分支结束时,弹出栈顶指针就可以
实际上采用的方法是dfs遍历每个结点然后加入到新的链表中。注意到此链表是没有头结点的单链表,同时要注意传递到函数中的指针的参数
用二级指针
class Solution {
public:
void dfs(Node* tail,Node** anstail,Node** anshead)
{
if(tail==NULL)
return;
Node* temp=(Node*)malloc(sizeof(Node));
temp->val=tail->val;
temp->next=NULL;
temp->prev=NULL;
temp->child=NULL;
//插入到tail的后面
if((*anstail)==NULL)
{
//没有头结点的链表的尾插法需要注意下面两行特别是
//head指针的赋值
(*anstail)=temp;
(*anshead)=(*anstail);
}
else
{
(*anstail)->next=temp;
temp->prev=*anstail;
(*anstail)=(*anstail)->next;
}
if(tail->child!=NULL)
{
dfs(tail->child,anstail,anshead);
}
dfs(tail->next,anstail,anshead);
}
Node* flatten(Node* head) {
Node* anshead=NULL;
Node* anstail=anshead;
dfs(head,&anstail,&anshead);
return anshead;
}
};
用引用
class Solution {
public:
void dfs(Node* tail,Node* &anstail,Node* &anshead)
{
if(tail==NULL)
return;
Node* temp=(Node*)malloc(sizeof(Node));
temp->val=tail->val;
temp->next=NULL;
temp->prev=NULL;
temp->child=NULL;
//插入到tail的后面
if(anstail==NULL)
{
anstail=temp;
anshead=anstail;
}
else
{
anstail->next=temp;
temp->prev=anstail;
anstail=anstail->next;
}
if(tail->child!=NULL)
{
dfs(tail->child,anstail,anshead);
}
dfs(tail->next,anstail,anshead);
}
Node* flatten(Node* head) {
Node* anshead=NULL;
Node* anstail=anshead;
dfs(head,anstail,anshead);
return anshead;
}
};
题解中可用dfs函数的返回值来标记一个分支的最后一个结点来解决原址修改的问题
class Solution {
public:
Node* dfs1(Node* p)
{
if(p==NULL)
return NULL;
if(p->next==NULL&&p->child==NULL)
return p;
if(p->child!=NULL)
{
Node* last1=dfs1(p->child);
Node* q=p->next;
p->next=p->child;
p->next->prev=p;
p->child=NULL;
if(q!=NULL)
{
last1->next=q;
q->prev=last1;
return dfs1(q);
}
else
return last1;
}
else
return dfs1(p->next);
}
Node* flatten(Node* head) {
dfs1(head);
return head;
}
};
官方的显然要更好一些
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;
}
};