五月集训 DAY13 【双向链表】

430.扁平化多级双向链表

你会得到一个双链表,其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针 。这个子指针可能指向一个单独的双向链表,也包含这些特殊的节点。这些子列表可以有一个或多个自己的子列表,以此类推,以生成如下面的示例所示的 多层数据结构 。
给定链表的头节点 head ,将链表 扁平化 ,以便所有节点都出现在单层双链表中。让 curr 是一个带有子列表的节点。子列表中的节点应该出现在扁平化列表中的 curr 之后 和 curr.next 之前 。
返回 扁平列表的 head 。列表中的节点必须将其 所有 子指针设置为 null 。

在这里插入图片描述输入: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]解释:输入的多级列表如上图所示。扁平化后的链表如下图:在这里插入图片描述
在这里插入图片描述

输入:head = [1,2,null,3] 输出:[1,3,2] 解释:输入的多级列表如上图所示。 扁平化后的链表如下图:
在这里插入图片描述

输入:head = []
输出:[]
说明:输入中可能存在空列表。

  • 节点数目不超过 1000
  • 1 <= Node.val <= 105

如何表示测试用例中的多级链表?

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

#include<vector>
#include<algorithm>
class Solution {
public:
    Node* flatten(Node* head) {
        vector<Node*> a;
        a.push_back(NULL);							//(1)
        Node* now = head;
        while(now){									//(2)
            if(now->child != NULL){
                a.push_back(now->next);	//将跳过的节点储存在a中
                now->next = now->child;	//深度优先
                now->child = NULL;
                now->next->prev = now;	//改前驱
            }
            now = now->next;			//不断向后遍历
        }
        int len = a.size()-1;						//(3)
        now = head;
        while(len){
            if(now->next == NULL){		//到达一行中最后一个节点时
                while(a[len] == NULL && len > 0){
                    len--;				//中间如果有空指针,就跳过
                }
                if(len == 0){
                    break;				//遍历到最后一行就跳出循环
                }
                now->next = a[len];		//改后继,改成上一次跳过的位置
                a[len]->prev = now;		//后继的前驱就是now本身
                len--;	
            }
            now = now->next;
        }
        return head;
    }
};

解题思路:
(1)建立一个结构体指针的数组vector<Node*> a。

  • a.push_back()在后面添加元素;a.size()获得a的长度。
  • 我的想法就是在一遍普通的遍历中,不断调整指针的指向,来达到我最终的目的。

(2)链表元素是分层的,而且层与层直接只有一个链接点,

  • 如果我在遍历的过程中找到了这个链接点child,就跳过该层后面的元素,
  • 把自己的下一个指针next改成child。
  • 并且记录我从哪里开始跳过的。
  • 这次的while循环目的主要是建立好我的a数组,找出每层在哪个位置跳过。顺便把child这条线给“拉直了”。

(3)len代表层数,代表我跳过了几次,我在0号位置加了空指针,

  • a[len]代表我最近一次的跳过的位置。
  • len递减,在len == 0 的时候,说明所有元素都访问了。
  • 如果中间有其他元素是空指针,我的指向就应该是上上层跳过的位置,所以加入了一个while循环跳过空指针。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值