LeetCode - 扁平化多级双向链表

一. 题目描述

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

扁平化列表,使所有结点出现在单级双链表中。您将获得列表第一级的头部。

示例:

输入:
 1---2---3---4---5---6--NULL
         |
         7---8---9---10--NULL
             |
             11--12--NULL

输出:
1-2-3-7-8-11-12-9-10-4-5-6-NULL

以上示例的说明:

给出以下多级双向链表:

我们应该返回如下所示的扁平双向链表:

 注:可耻地截图了,LeetCode大大,如果有需要,可以联系我删除截图。

二. 解题思路

这道题很容易想到解题思路,基本思路就是从前往后遍历,遇到有子节点的,特殊处理,处理后,继续遍历直到结束。

那么难点就在于如何进行子节点的处理,很容易想到的思路是,从前往后去遍历,遇到子节点就从上往下去处理,也就是一个深度优先的策略,但这样子感觉处理起来有点复杂,因为不断地往下深入,你需要记住的信息会很多,每往下一层就需要记住每一层的父节点和父节点的下一个兄弟节点,那么,这个数量是不可预估的,实现麻烦,反正我是没有继续再往下思考了,因为觉得挺麻烦的。

那么换一个思路,上一个方法的问题在于需要记住多的不确定数量的节点信息,那么有没有办法记住少量且固定数量节点信息的方法呢,并且难点依旧是在处理子节点和子节点处理后的链表拼接上。顺着这个思路,我想到一个方法,只处理第一层的子节点,这样就只需要记住第一层具有子节点的父节点和此父节点的下一个兄弟节点即可,然后将子节点所指向的整条链表拼接到父节点所在的层中,其实就是第一层。这样的话,只需要记住第一层的具有子节点的父节点,以及其子节点和下一个节点这三个节点信息即可,然后让父节点的next指针指向子节点,子节点的链表末尾指向原父节点的next。然后当前指针指向原子节点,继续往后遍历知道结束即可。

如何还不明白(全怪你的表达得恏,你个沙雕)。这个过程可以分成两步来做。

1. 遍历一次链表,遇到有子节点的,将其子节点变成其next节点,子节点指向的链表末尾指向原next节点,然后从原next节点继续往后遍历,直到结束,不断循环此过程,知道链表中没有节点具有子节点。

2. 优化遍历过程,不需要不断循环此过程也能一次遍历完成目标。(这个就需要你自己观察了,啊啊,我懒得写了,宇宙级懒人)。

三. 代码

说了一堆没用的,还是直接贴代码吧。

/*
// Definition for a Node.
class Node {
    public int val;
    public Node prev;
    public Node next;
    public Node child;

    public Node() {}

    public Node(int _val,Node _prev,Node _next,Node _child) {
        val = _val;
        prev = _prev;
        next = _next;
        child = _child;
    }
};
*/
class Solution {
    public void flatten_child(Node pre, Node child, Node next){
        pre.next = child;
        child.prev = pre;
        pre.child = null;
        
        Node now = child;
        while(now.next != null){
            now = now.next;
        }
        
        now.next = next;
        if( next != null )
            next.prev = now;
        
    }
    public Node flatten(Node head) {
        Node node = head;
        
        while(node != null){
            if( node.child != null ){
                flatten_child(node, node.child, node.next);
            }
            node = node.next;
        }
        return head;
    }
}

 其实还有别的更快的法子,不过这样写比较简洁,不需要使用其他数据结构(栈),而且时间复杂度也比较可以接受,最坏情况估计是O(n^2),

四. 引用

leetcode:https://leetcode-cn.com/explore/learn/card/linked-list/197/conclusion/764/

猜你喜欢

转载自blog.csdn.net/qq_28634403/article/details/89086848