扁平化双向链表

多级双向链表中,除了指向下一个节点和前一个节点指针之外,它还有一个子链表指针,可能指向单独的双向链表。这些子列表也可能会有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。

给你位于列表第一级的头节点,请你扁平化列表,使所有结点出现在单级双链表中。

示例 1:

输入:head = [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]
输出:[1,2,3,7,8,11,12,9,10,4,5,6]
解释:

输入的多级列表如下图所示:

扁平化后的链表如下图:

我们从头开始遍历,遇到有子节点的就把其子链表先扁平化,然后把子链表插入到当前节点和next节点之间即可。

DFS 在这里的作用就是先保证子链表已经扁平化,再扁平化当前层的链表,这样,最后全部处理完成就全部扁平化了。

/*
// 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) {
        // 遍历每一个节点,看它是否有子节点,有子节点的话,把它的子节点那一坨放在它和next之间
        dfs(head);
        return head;
    }
    void dfs(Node node){
        //退出条件
        if (node == null) {
            return;
        }
        //子节点不为空
        if(node.child != null){
            Node next = node.next;
            //先子链扁平化
            dfs(node.child);
            //把子节点的下一个节点放入主链的下一个借点,并把子节点的上一个节点当作当前节点
            node.next = node.child;
            node.child.prev = node;
            // 寻找扁平化之后的子节点的最后一个节点(即子链表的尾)
            Node tail = node.child;
            while (tail.next != null) {
                tail = tail.next;
            }
            //把子链表的尾巴和主链条的头节点链接
            if(next != null){
                next.prev = tail;
            }
            tail.next = next;
            //子链条为空
            node.child = null;
        }else {
            // 子节点为空,不需要处理
            dfs(node.next);
        }
    }
}
posted @ 2021-09-24 13:06  落笔生花  阅读(13)  评论(0)    收藏  举报