430.扁平化多级双向链表

你会得到一个双链表,其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针 。这个子指针可能指向一个单独的双向链表,也包含这些特殊的节点。这些子列表可以有一个或多个自己的子列表,以此类推,以生成如下面的示例所示的 多层数据结构 。

给定链表的头节点 head ,将链表 扁平化 ,以便所有节点都出现在单层双链表中。让 curr 是一个带有子列表的节点。子列表中的节点应该出现在扁平化列表中的 curr 之后 和 curr.next 之前 。

返回 扁平列表的 head 。列表中的节点必须将其 所有 子指针设置为 null 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/flatten-a-multilevel-doubly-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

读题的时候看题目的示意图,发现只要有子结点的结点node,它的子链表就会放在它自身和node.next之间。因此我们可以这样想:当我们向后遍历链表的时候,如果发现了结点node有子链表node.child,就先把node.next给它放在temp里面存起来,然后来处理子链表,把node.next指向扁平化后的子链表;处理完子链表,就要将temp重新放到原链表的结尾,所以要设置一个指针remain,它要继续向后遍历到下一个结点为空,循环条件为remain.next!=null ,之后将remain.next = temp,然后继续往下处理。

思路整理完毕,我们就可以开始写代码了。

但这题最恶心的地方在于你可能输出的答案是对的,但是新的链表已经是无效的双链表了,意味着你的某些结点的prev指向null或者其他地方。所以在每一次处理子链表的时候,要记得将子链表的prev指向它的父链表,将node.next.prev指向该指向的地方;

public static Node flatten(Node head) {
    if(head == null ){
        return  null;
    }
    if(head.next==null){
        Node next = flatten(head.child);
        head.next = next;
        if(next!=null){
            //把双向链表完善
            next.prev = head;
        }
        return head;
    }

    Node cur = head;
    while(cur!=null){
        if(cur.child!=null){
            Node temp = cur.next;
                //完善双向链表
            cur.child.prev=cur;
            cur.next=cur.child;
            Node remain = cur.child;
            while(remain.next!=null){
                remain = remain.next;
            }
                //递归处理子链表
            Node next = flatten(temp);
            if(next!=null){
                //完善双向链表
                next.prev = remain;
            }
            remain.next = next;
        }
        cur.child = null;
        cur = cur.next;
    }
    return head;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值