递归展平
之所以写两个方法,是因为一个需要返回链表的头节点,一个需要返回链表的尾节点。
我们顺序遍历链表
如果需要子节点不为空的,那说明我们需要展平这个子链表的所有内容,并将子链表接到这个链表上
递归检查,逐层展平即可
/*
// Definition for a Node.
class Node {
public:
int val;
Node* prev;
Node* next;
Node* child;
};
*/
class Solution {
public:
Node* flatten(Node* head) {
// 递归算法
Node* p = head; // 遍历指针
while(p){
// 如果子节点不为空则将其提上来,否则向下遍历
if(p->child!=NULL){
//Node* c = p->next;
Node* q = p->child;
Node* t = flatten_b(p->child); // 展平子节点,获取子节点的尾部
// 拼接
t->next = p->next;
if(p->next!=NULL) p->next->prev = t;
p->next = q;
q->prev = p;
p->child = NULL;
p = p->next;
}else{
p = p->next;
}
}
return head;
}
// 寻找展平后的尾部
Node* flatten_b(Node* head){
if(head==NULL){
return head;
}
Node* p = head; // 遍历指针
while(p->next!=NULL){
// 如果子节点不为空则将其提上来,否则向下遍历
if(p->child!=NULL){
// Node* c = p->next;
Node* q = p->child; // 获取子节点的头
Node* t = flatten_b(p->child); // 子链表的尾
// 拼接
t->next = p->next;
if(p->next!=NULL) p->next->prev = t;
p->next = q;
q->prev = p;
p->child = NULL;
p = p->next;
}else{
p = p->next;
}
}
// cout<<"尾节点:"<<p->val<<endl;
return p;
}
};