算法修炼之路——【链表】Leetcode 430 扁平化多级双向链表

题目描述

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

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

示例1:

输入: head = [1, 2, 3, 4, 5, 6, null, null, null, 7, 8, 9, 10, null, null, 11, 12]
输出: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
解释
在这里插入图片描述
** 图1**

示例2:

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

说明:

  • 节点数目不超过1000
  • 1 <= node.val < 10E5

思路分析

我们看到题干首先想到的是,深度优先搜索算法,所以我们直接借助stack保存具有child非空指针后的节点,当深度遍历完之后,从stack中弹出保存点,接着遍历。

在这里插入图片描述
图2

扫描二维码关注公众号,回复: 10972778 查看本文章

我们通过图2可知,设遍历指针为curr,红色箭头为curr的遍历轨迹:

  1. 当存在child节点时,将curr.next压入栈中,直接遍历curr.child
  2. 当在下沉过程中,又检测到child节点,则重复步骤1
  3. 在最后一级链表到尽头时,检测栈是否为空:不为空则弹出栈顶元素(返回上一级链表);为空则完成多级链表的遍历,直接输出结果output.

解题步骤

  1. 初始化两个分区指针oddTail, evenTail和布尔变量isOddNode
  2. 遍历原始链表,根据isOddNode判断evenTail.next是否插入奇数分区;
  3. evenTail.next == null时停止并返回head.

解题代码

    public static ListNode solution(ListNode head) {
        if (head == null) {
            return head;
        }

        /* Step1: Init. pointers */
        Stack<ListNode> stack = new Stack<>();
        ListNode curr = head;

        /* Step2: go through the head-list
        and
        go back last level when no more subsequent child and next nodes
         */
        while (curr != null) {
            // exists child-node
            if (curr.child != null) {
                ListNode node = curr.next;
                stack.push(node);

                curr.next = curr.child;
            }

            // back to last level
            if (curr.next == null && !stack.isEmpty()) {
                curr.next = stack.peek();
                curr = stack.pop();
            }

            curr = curr == null ? null : curr.next;
        }
        /* Step3: return head */
        return head;
    }

复杂度分析

时间复杂度:我们对原始链表进行了一次遍历,容易理解时间复杂度为O(N);
空间复杂度:我们这里设置了辅助容器stack,故空间复杂度为O(N).

GitHub源码

完整可运行文件请访问GitHub

发布了47 篇原创文章 · 获赞 55 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/u011106767/article/details/105572842