zoukankan      html  css  js  c++  java
  • LeetCode 430:扁平化多级双向链表 Flatten a Multilevel Doubly Linked List

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

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

    You are given a doubly linked list which in addition to the next and previous pointers, it could have a child pointer, which may or may not point to a separate doubly linked list. These child lists may have one or more children of their own, and so on, to produce a multilevel data structure, as shown in the example below.

    Flatten the list so that all the nodes appear in a single-level, doubly linked list. You are given the head of the first level of the list.

    示例:

    输入:
     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
    

    以上示例的说明:

    给出以下多级双向链表:

    img

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

    解题思路:

    这道题是典型的 DFS(深度优先搜索)型例题,并且给出了图解,只要了解过 DFS 的应该立即就能想到思路。

    针对这道题简单说下:深度优先搜索 就像一棵树(二叉树)的前序遍历,从某个顶点(链表头节点)出发,自顶向下遍历,然后遇到顶点的未被访问的邻接点(子节点 Child),继续进行深度优先遍历,重复上述过程(递归),直到所有顶点都被访问为止。

    其逻辑以示例输入为例:

     1---2---3---4---5---6--NULL
           |
            7---8---9---10--NULL
                  |
                 11---12---NULL
    
    从节点 1 开始遍历,当前遍历链表为:1---2---3---4---5---6--NULL
    
    遇到邻接点 2,其子链表为:7---8---9---10--NULL
    将子链表头节点 7 作为参数传入 DFS 函数,当前遍历链表为:7---8---9---10---NULL
    
    继续遍历,遇到邻接点 8,其子链表为:11--12--NULL
    将子链表头节点 8 作为参数传入 DFS 函数,当前遍历链表为:11--12---NULL
    
    继续遍历,无邻接点,遍历结束,返回当前链表尾节点 12
    改变邻接点 8 与子链表头节点 11 关系:7---8---11---12
    连接返回值 尾节点 12 和邻接点的下一个节点 9: 7---8---11---12---9---10---NULL
    
    继续遍历,无邻接点,遍历结束,返回当前链表尾节点 10
    改变邻接点 2 与 子链表头节点 7 关系:1---2---7---8---11---12---9---10--NULL
    连接返回值 尾节点 10 和邻接点的下一个节点 3: 1---2---7---8---11---12---9---10---3---4---5---6--NULL
    
    继续遍历,无邻接点,遍历结束,返回当前链表尾节点 6
    
    递归结束,返回头节点 1,链表为: 1---2---7---8---11---12---9---10---3---4---5---6--NULL
    

    Java:

    class Solution {
        public Node flatten(Node head) {
            dfs(head);
            return head;
        }
    	//深度优先搜索函数
        private Node dfs(Node head) {
            Node cur = head;
            while (cur != null) {
                if (cur.child != null) {
                    //改变当前节点与子节点的关系
                    Node next = cur.next;//记录暂存下一个节点
                    cur.next = cur.child;//当前节点与子链表头节点连接
                    cur.next.prev = cur;
    				//传递子链表头节点作为参数到 dfs
                    Node childLast = dfs(cur.child);//childLast获得返回值为子链表的尾节点
                    childLast.next = next;//子链表尾节点与暂存节点连接
                    if (next != null) next.prev = childLast;//暂存节点不为空就将其prev指向子链表尾节点
                    cur.child = null;//子链表置空
                    cur = childLast;//刷新当前节点,跳过子链表的遍历
                }
                head = cur;//头节点刷新为当前节点
                cur = cur.next;//刷新当前节点
            }
            return head;//返回子链表的尾节点
        }
    }
    

    Python3:

    class Solution:
        def flatten(self, head: 'Node') -> 'Node':
            self.dfs(head)
            return head
    
        def dfs(self, head):
            cur = head
            while cur:
                if cur.child:
                    next = cur.next
                    cur.next = cur.child
                    cur.next.prev = cur
                    childLast = self.dfs(cur.child)
                    childLast.next = next
                    if next: next.prev = childLast
                    cur.child = None
                head = cur
                cur = cur.next
            return head
    

    欢迎关注微.信公.众号:爱写Bug

    爱写Bug.png

  • 相关阅读:
    【OpenStack】OpenStack系列16之OpenStack镜像制作
    【OpenStack】OpenStack系列15之OpenStack高可用详解
    【OpenStack】OpenStack系列14之Dashboard定制开发
    【OpenStack】OpenStack系列13之Nova源码解析与API扩展
    linux之scp命令
    阿里大鱼短信平台
    count(1)与count(*)
    java中枚举类到高级使用
    idea中mybatis-plugin破解
    mmall项目之问题一(mavenplugin问题)
  • 原文地址:https://www.cnblogs.com/zhangzhe532/p/11253909.html
Copyright © 2011-2022 走看看