总的来说 :就是遍历一个链表,如果 child 为 null,则继续遍历下一个节点,但如果 child 不为 null,也就是说中止当前链表遍历,遍历 当前节点的child 所在链表,那么下一次遍历的节点就是从child指向的节点开始(并插入到当前链表节点的next位置),直到遍历完 child 所在的链表所有节点(前提是 child 所在的链表的所有节点 的child 都为 null,否则,按照前面说的,中止遍历当前链表,优先遍历完 child 所在链表)。遍历完后,继续上部分还未遍历完的链表(插入完child所在链表的所有节点,将其尾巴节点,接回原先链表中,继续遍历上部分链表未遍历的部分)。【遍历的过程,包含链接。】
因为我们无法确定该链表中所有节点 的 child 是否为 null,或者 child 所在链表的节点总数,所以一开始是无法确定 最后结果的节点位置。
如果是,我们就需要记录 cur 的 next 值。(当然提前创建一个变量来记录)
方便 最后将 child 所在链表 的所有节点 插入 上部分链表时,收尾部分(将child所在链表的尾结点,上部分中断的位子,进行链接,从而真正接入原先链表中)
这里,我使用递归思想。来看!
然后我们就需要去思考:这个递归的终止条件是 cur,child == null,对不对?
来想一想:在递归结束的时候,我们继续遍历当前递归到child所在链表,直到遍历完当前链表的所有节点,如果当前链表中的节点还存在 child,无非,就是在递归一次,然后就跟我们现在一样,就需遍历当前链表。
在此过程 last 永远指向都是 当前链表中最后一个节点。(也就是child 的 尾巴节点)
而我们,要将child 所在链表的节点全部插入进来,就需要最后一个节点的位置。
你可以比较一下.
/* // Definition for a Node. class Node { public int val; public Node prev; public Node next; public Node child; }; */
class Solution {
public Node flatten(Node head) {
pancake(head);
return head;
}
public Node pancake(Node node){
Node cur = node;
Node last = null;
while(cur != null){
Node next = cur.next;
if(cur.child != null){
Node childLast = pancake(cur.child);
next = cur.next;// 将next 更新到 目前 cur 的 next值。
// 解决善后问题后:我们是继续遍历 原先链表的
// 开头链接
cur.next = cur.child;
cur.child.prev = cur;
if(next != null){// 如果next 为null,善后工作就没必要了
childLast.next = next;
next.prev = childLast;
}
cur.child = null;
last = childLast;
}else{
last = cur;
}
cur = next;
}
return last;
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/DarkAndGrey/article/details/122269578
内容来源于网络,如有侵权,请联系作者删除!