leetcode每日一题系列-扁平化多级双向链表-「递归」-「非递归」

195 阅读2分钟

leetcode-430-扁平化多级双向链表

[博客链接]

菜🐔的学习之路

掘金首页

[题目链接]

题目链接

[github地址]

github地址

[题目描述]

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

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

 

示例 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 示例 3:

输入:head = [] 输出:[]  

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

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

提示:

  • 节点数目不超过 1000
  • 1 <= Node.val <= 10^5

思路一:递归解法

  • 如果head为空直接返回即可
  • 否则每次遍历所有子节点,记录当前节点,然后拼接后跨越下个节点
  • 注意前后指针的赋值关系
public Node flatten(Node head) {
    //corner case
 if (head == null){
     return head;
 }
 Node dummy = new Node(0,null,head,null);
 dfs(dummy,head);
 dummy.next.prev = null;
 return dummy.next;
}

public Node dfs(Node pre, Node cur) {
    if (cur == null){
        return pre;
    }
    pre.next = cur;
    Node temp = cur.next;
    cur.prev = pre;
    Node tail = dfs(cur,cur.child);
    cur.child = null;
    return dfs(tail ,temp);

}
  • 时间复杂度O(n)
  • 空间复杂度O(1)

思路二:非递归解法

  • 定义一个栈存储节点
  • 先放入同级后续节点
  • 后放入子节点
  • 然后反向弹出拼接即可
public Node flatten(Node head) {
    if (head == null){
        return head;
    }
    Node dummy = new Node(0,null,head,null);
    Node pre = dummy;
    Node cur = head;
    Stack<Node> stack = new Stack<>();
    stack.push(head);
    while (!stack.isEmpty()){
        cur = stack.pop();
        pre.next = cur;
        cur.prev = pre;
        if (cur.next != null){
            stack.push(cur.next);
        }
        if (cur.child != null) {
            stack.push(cur.child);
            // don't forget to remove all child pointers.
            cur.child = null;
        }
        pre = cur;
    }
    dummy.next.prev = null;
    return dummy.next;
}
  • 时间复杂度O(n)
  • 空间复杂度O(n)