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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 扁平化多级双向链表/Leedcode/源码/C++ -> 正文阅读

[数据结构与算法]扁平化多级双向链表/Leedcode/源码/C++

430. 扁平化多级双向链表

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

给你位于列表第一级的头节点,请你扁平化列表,使所有结点出现在单级双链表中。

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

解释:

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

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

在这里插入图片描述扁平化后的链表如下图:

在这里插入图片描述
将脖子歪45°,可以简单看出扁平化相当于先序遍历一个树,树的遍历具体可见我的另一个文章(https://blog.csdn.net/mountains_L/article/details/115304102),但是这只是本题第一个简单的难点。

根据链接的代码先序遍历树,在此过程中将结点重排,如下代码

Node* flatten(Node* head) {
    stack<Node*> s;
    Node* p = head;
    Node* pre = NULL;
    while (p || !s.empty()) {
        while (p) { //进入左子树最下
            s.push(p); //入栈
            if(pre != NULL) pre->next = p;
            p->prev = pre;
            pre = p;
            p = p->child;
            pre->child = NULL;
        }
        if (!s.empty()) {
            p = s.top(); //出栈
            s.pop();
            p = p->next;
        }
    }
    return head;
}

乍一看感觉挺对的,但是跑一下就发现是错的,问题出在下图语句1处,以实例为例,p指向结点7时,pre为3,3->next被修改为7,在结点7遍历之后将回溯到结点3时,需要在语句2处进入3->next,这时就又前往3,而不是原来的4了。
在这里插入图片描述

那么,如何做到既修改了先序遍历中父节点的next(rchild),又能在回溯到父节点时能顺利进入next(rchild)呢?有一个办法,在入栈时(语句3)不记录父节点,而直接记录next(rchild),在回溯时不从父节点进入next(rchild),而直接进入next(rchild)(反正前序遍历,父节点在右孩子之前已被遍历,父节点无用)。这样就可以随心所欲的改变父节点的next(rchild)。全部源码如下图所示:

Node* flatten(Node* head) {
    stack<Node*> s;
    Node* p = head;
    Node* pre = NULL;
    while (p || !s.empty()) {
        while (p) { //进入左子树最下
            if(p->next) s.push(p->next); //入栈
            if(pre != NULL) pre->next = p;
            p->prev = pre;
            pre = p;
            p = p->child;
            pre->child = NULL;
        }
        if (!s.empty()) {
            p = s.top(); //出栈
            s.pop();
        }
    }
    return head;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 10:26:26  更:2021-09-26 10:27:03 
 
开发: 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 4:37:09-

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