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
以上示例的说明:
给出以下多级双向链表:

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

解题思路:
这道题是典型的 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

LeetCode 430:扁平化多级双向链表 Flatten a Multilevel Doubly Linked List的更多相关文章
- Java实现 LeetCode 430 扁平化多级双向链表
430. 扁平化多级双向链表 您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表.这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例 ...
- Leetcode 430.扁平化多级双向链表
扁平化多级双向链表 您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表.这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示. 扁 ...
- LeetCode430 扁平化多级双向链表
您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表.这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示. 扁平化列表,使所有结点 ...
- 【LeetCode】430. Flatten a Multilevel Doubly Linked List 解题报告(Python)
[LeetCode]430. Flatten a Multilevel Doubly Linked List 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: ...
- [LeetCode] Flatten a Multilevel Doubly Linked List 压平一个多层的双向链表
You are given a doubly linked list which in addition to the next and previous pointers, it could hav ...
- LeetCode 430. Flatten a Multilevel Doubly Linked List
原题链接在这里:https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/description/ 题目: You a ...
- [LC] 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 hav ...
- 430. Flatten a Multilevel Doubly Linked List
/* // Definition for a Node. class Node { public: int val = NULL; Node* prev = NULL; Node* next = NU ...
- LeetCode 430. Faltten a Multilevel Doubly Linked List
题目链接:LeetCode 430. Faltten a Multilevel Doubly Linked List class Node { public: int val = NULL; Node ...
随机推荐
- 【计算机网络】如何让Ajax通信过程携带Cookie呢?
Ajax 1. 介绍一下ajax并代码实现 1.1 基本概念 JavaScript 和XML(Asynchronous JavaScript And XML).简单点说,就是使用 XMLHttpReq ...
- Linux中的buff/cache内存
我们用free.top等相关能够查询到当前内存的使用情况的命令时,总会有一个buff/cache让我们很困惑. buffer 即写如磁盘时,先保存到磁盘缓冲区(buffer),然后再写入到磁盘. ca ...
- Idea-搜索快捷键
1.Ctrl+N按名字搜索类 相当于eclipse的ctrl+shift+R,输入类名可以定位到这个类文件,就像idea在其它的搜索部分的表现一样,搜索类名也能对你所要搜索的内容多个部分进行匹配,而且 ...
- python3报'ascii' codec can't encode characters in position 0-7: ordinal not in range(128)解决方法
运行前指定export PYTHONIOENCODING为utf-8 如 export PYTHONIOENCODING=utf-8; python main.;y
- int[]里数的个数怎么由输入决定?-----动态数组。
java中如何创建动态数组?(摘自百度知道) Java动态数组是一种可以任意伸缩数组长度的对象,在Java中比较常用的是ArrayList,ArrayList是javaAPI中自带的java.util ...
- django3-视图函数进阶
1.视图函数的分类 FBV(fucntion base view) CBV(class base view) ,CBV根据定义的方法名 ,判断什么请求执行什么函数 2.FBV转换CBV (不太对劲) ...
- Html 页面底部添加版权信息
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 双十一DIY装机记
一.装机背景 最近发现古董笔记本太卡了,用了近6年,尽管自己不打游戏,但是业余时间写写代码,同时开两个编辑器,打开个大一点的软件都卡的不行,据说更换固态硬盘可以提高速度,于是乎,京东买了一个500 ...
- 实战FFmpeg--编译iOS平台使用的FFmpeg库(支持arm64的FFmpeg2.6.2)
编译环境:Mac OS X 10.10.2 ,Xcode 6.3 iOS SDK 8.3 FFmpeg库的下载地址是 http://www.ffmpeg.org/releases/ . ...
- redis分享
Redis介绍 ´Redis是一种基于键值对的NoSQL数据库. ´Redis基于内存来存放数据. ´速度快,官方给出读写性能可达到10万/秒(数据存内存,C语言实现,单线程架构). ´丰富的数据结构 ...