「每日一题」扁平化多级双向链表

360 阅读2分钟

这是 LeetCode 上 2021-9-24 的每日一题:「430. 扁平化多级双向链表」

1. 题目描述

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

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

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

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

扁平化后的链表如下图:

示例 2:

输入:head = [1,2,null,3]
输出:[1,3,2]
解释:

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

  1---2---NULL
  |
  3---NULL

2. 解答

  1. 创建虚拟节点res,最后返回虚拟节点的next,并将res.next.prev置空
  2. 头部节点入栈,用栈遍历链表节点,构造双向链表的连接
  3. 若遇到nextchild,先进next,后进child,这样下一轮就可以先遍历child
const flatten = head => {
    if (!head) return head;
    const res = new Node(-1, null, null, null);
    // prev指针
    let prev = res;
    // 头部节点入栈
    const stack = [head];
    while (stack.length) {
        // 栈顶元素出栈,当前指针指向栈顶元素
        const cur = stack.pop();
        // 双向连接
        prev.next = cur;
        cur.prev = prev;
        // 栈先入后出,先进 next,后进child
        if (cur && cur.next) {
            stack.push(cur.next);
        }
        if (cur && cur.child) {
            stack.push(cur.child);
            // child要置空
            cur.child = null;
        }
        // 更新上一节点
        prev = cur;
    }
    // 将头部与res节点的prev断开
    res.next.prev = null;
    return res.next;
};

😄最近新创建了个开源仓库,总结 LeetCode 的每日一题,目前已有 C++、JavaScript 语言版本,欢迎大家提供其他语言版本!

🖥️仓库地址:「每日一题系列」