CS-Wiki CS-Wiki
Home
知识体系总览
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • MySQL
  • Redis
  • 设计模式
  • Java 基础
  • Java 集合
  • Java 并发
  • Java 虚拟机
  • Spring
  • Kafka
  • 校招扫盲
  • 项目推荐
  • 唠唠嗑儿
  • 读书笔记
归档
GitHub (opens new window)
Home
知识体系总览
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • MySQL
  • Redis
  • 设计模式
  • Java 基础
  • Java 集合
  • Java 并发
  • Java 虚拟机
  • Spring
  • Kafka
  • 校招扫盲
  • 项目推荐
  • 唠唠嗑儿
  • 读书笔记
归档
GitHub (opens new window)
  • 刷题模板汇总
  • 一些刷题小技巧
  • 整数 and 位运算

  • 数组

  • 链表

  • 哈希表

  • 字符串

  • 栈

  • 队列

  • 二叉树

  • 前缀树

  • 二分查找

  • 双指针法

  • 区间求和问题

  • 排序

  • 回溯算法

  • 贪心算法

  • 动态规划

  • 图

    • 图理论基础
    • 图的搜索:DFS

      • 岛屿的最大面积:BFS 和 DFS 模板
      • 岛屿数量
      • 节点间通路
      • 二分图
      • 所有路径:需要存储路径的 DFS 模板
      • 单词搜索:DFS + 回溯模板
      • 计算除法
      • 最长递增路径:记忆化 DFS 模板
      • 二叉树中所有距离为 K 的结点
      • 克隆图
      • 剑指 Offer 17 - 打印从 1 到最大的 n 位数
      • 剑指 Offer 35 - 复杂链表的复制
      • 展平多级双向链表
        • 📃 题目描述
        • 🔔 解题思路
        • 💥 复杂度分析
    • 图的搜索:BFS

    • 拓扑排序

    • 并查集

  • 数学

  • 自动机

  • 海量数据和空间限制

  • 05-数据结构与算法
  • 图
  • 图的搜索:DFS
小牛肉
2022-04-12
目录

展平多级双向链表

# 📃 题目描述

题目链接:

  • 剑指 Offer II 028. 展平多级双向链表 - 力扣(LeetCode) (leetcode-cn.com) (opens new window)
  • 430. 扁平化多级双向链表 - 力扣(LeetCode) (leetcode-cn.com) (opens new window)

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

给定位于列表第一级的头节点,请扁平化列表,即将这样的多级双向链表展平成普通的双向链表,使所有结点出现在单级双链表中。

示例 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]

解释:

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

扁平化后的链表如下图:

image-20220413115438086

解释下:

以 示例 1 为例:

1---2---3---4---5---6--NULL | 7---8---9---10--NULL | 11--12--NULL 序列化其中的每一级之后:

[1,2,3,4,5,6,null]
[7,8,9,10,null]
[11,12,null]

为了将每一级都序列化到一起,我们需要每一级中添加值为 null 的元素,以表示没有节点连接到上一级的上级节点。

[1,2,3,4,5,6,null]
[null,null,7,8,9,10,null]
[null,11,12,null]

合并所有序列化结果,并去除末尾的 null 。

[1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]

# 🔔 解题思路

理解题目很重要

其实很简单

比如有 a —> b 这样两个节点,然后 a 还有一个 child 指针,指向一个新的链表,题目就是要把这个 child 链表插入到 a 和 b 之间。

所以,对于这个插入操作,我们需要四个关键信息:

  • a 节点
  • a 的 next 节点:b
  • a 的 child 链表的头节点
  • a 的 child 链表的尾节点
/*
// 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) {
        dfs(head);
        return head;
    }

    // dfs 展平以 head 为头节点的链表之后返回链表的尾节点
    public Node dfs(Node head) {
        Node node = head;
        Node tail = null;

        while (node != null) {
            // 记录 node 后继节点
            Node next = node.next;
            if (node.child != null) {
                Node child = node.child;
                // 递归调用展平 child,返回尾节点
                Node childTail = dfs(child);

                // 删除 child 指针
                node.child = null;
                
                // 将 child 链表插入 node 和 node.next 之间
                node.next = child;
                child.prev = node;
                childTail.next = next;
                if (next != null) {
                    next.prev = childTail;
                }

                tail = childTail;
            }
            // 如果 node 没有 child,那么无须展平
            else {
                tail = node;
            }

            node = next;
        }

        return tail;
    }
}

在上述代码中,递归函数 flattenGetTail 在展平以head为头节点的链表之后返回链表的尾节点。在该函数中需要逐一扫描链表中的节点。如果一个节点node有子链表,由于子链表也可能有嵌套的子链表,因此先递归调用 flattenGetTail 函数展平子链表,子链表展平之后的头节点是child,尾节点是childTail。

最后将展平的子链表插入节点node和它的下一个节点next之间,即把展平的子链表的头节点child插入节点node之后,并将尾节点childTail插入节点next之前。

# 💥 复杂度分析

  • 空间复杂度:函数 flattenGetTail 的递归调用次数取决于链表嵌套的层数,因此,如果链表的层数为 k,那么该节点的空间复杂度是 O(K)
  • 时间复杂度:法每个节点都会遍历一次,如果链表总共有 n 个节点,那么时间复杂度是 O(n)

🎁 公众号

各位小伙伴大家好呀,叫我小牛肉就行,目前在读东南大学硕士,上方扫码关注公众号「飞天小牛肉」,与你分享我的成长历程与技术感悟~

帮助小牛肉改善此页面 (opens new window)
Last Updated: 2023/02/16, 11:27:10
剑指 Offer 35 - 复杂链表的复制
矩阵中的距离

← 剑指 Offer 35 - 复杂链表的复制 矩阵中的距离→

最近更新
01
我掏出这个多线程轮子,面试官直接全体起立
04-13
02
面试官问你有其他 Offer 吗,该怎样回答
04-10
03
天不生陈志龙,职场万古如长夜
04-06
更多文章>
Theme by Vdoing | Copyright © 2019-2023 飞天小牛肉 | 皖ICP备2022008966号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式