IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Leetcode--Java--430. 扁平化多级双向链表 -> 正文阅读

[数据结构与算法]Leetcode--Java--430. 扁平化多级双向链表

题目描述

在这里插入图片描述

样例描述

在这里插入图片描述

思路

方法一:递归 + 迭代 O(n^2)

  1. 没孩子结点就一直next,如果有孩子结点,就先存储当前结点的下一个,然后不断递归(将孩子部分先展平),随后拼接当前结点和展平后的部分,并将当前结点的孩子指针设置为null,然后寻找展平部分的最后一个结点与原始当前结点的下一个结点进行拼接。 最后将当前结点设置为原始的下一个,准备下一轮迭代。

方法二:对方法一的优化:额外写递归函数 O(n)

  1. 方法一中由于每次是从head.child开始递归,又要每一次再次遍历寻找展平部分的尾结点。这里最坏情况复杂度是平方。
  2. 单独写递归函数,每次直接返回展平后的"尾结点",使得找尾结点的部分不会在每一层出现,可以达到O(n)
    递归拼接顺序如下:
    在这里插入图片描述

方法三: 迭代
迭代的拼接顺序与递归不同,是一段一段进行的,区别如下:
在这里插入图片描述

  1. 让head从最开始一直走,只要child不为空,就先迭代拼接处理完child层,然后继续往后,碰到有child就拼接。(虽然head会越遍历越长,因为不断拼接了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) {     
        Node dummy = new Node(-1);
        dummy.next = head;
        while (head != null) {
            if (head.child == null) {
                head = head.next;
            } else {
                //先存下当前的下一个结点
                Node nextN = head.next;
                //递归不断地展平,得到展平后的第一个结点
                Node flatnode = flatten(head.child);
                //将当前结点与展平后那块链表进行拼接
                head.next = flatnode;
                flatnode.prev = head;
                //这里要让孩子指针为null,因为上面已经展平
                head.child = null;
                //寻找展平后的最后一个结点,与原始head的下一个结点进行拼接 (也就是融入head所在层)
                while (head.next != null) {
                    head = head.next;
                }
                head.next = nextN;
                //这里一定要判断下是否为null,不然空会有异常
                if (nextN != null)
                nextN.prev = head;
                //然后让head更新为next,准备下一轮迭代
                head = nextN;
            }
        }
        return dummy.next;
    }
}

方法二:优化递归

/*
// 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;
    }
    //返回展平后的尾结点,返回给上一层使用
    public Node dfs(Node head) {
        Node last = head;
        while (head != null) {
            if (head.child == null) {
                last = head;
                head = head.next;
            } else {
                Node nextN = head.next;
                Node lastChild = dfs(head.child);
                //拼接head以及head的下一个
                head.next = head.child;
                head.child.prev = head;
                //孩子指针设置为空
                head.child = null;
                //让最后一个和上层head的下一个拼接
                lastChild.next = nextN;
                if (nextN != null) {
                    nextN.prev = lastChild;
                }
                //准备下一轮,到最后一个  不能到nextN
                head = lastChild;
            }
        }
        return last;
    }
}

方法三:

/*
// 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) {
        Node dummy = new Node(-1);
        dummy.next = head;
        while (head != null) {
            //有孩子
            if (head.child != null) {
                Node t = head.next;
                Node child = head.child;
                head.next = child;
                child.prev = head;
                head.child = null;
                //迭代找尾结点
                Node last = child;
                while (last.next != null) {
                    last = last.next;
                }
                last.next = t;
                if (t != null) {
                    t.prev = last;
                }
            } 
            head = head.next;
        }
        return dummy.next;
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:39:43  更:2022-03-03 16:44:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 15:33:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码