Flatten a Multilevel Doubly Linked List

MediumLinked List · DFS · In-place Splicing🧩 Linked List TechniquesLeetCode #430 ↗Updated

Problem

Each node of a doubly linked list has prev, next and an extra child pointer that may lead to another doubly linked list, which can have children of its own. Flatten the structure into one level: a node's child list must appear right after that node and before its old next. Set every child to null, keep prev links correct, and return the head.
Input[1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]Output[1,2,3,7,8,11,12,9,10,4,5,6]
Input[1,2,null,3]Output[1,3,2]
Input[]Output[]

0 ≤ number of nodes ≤ 1000  ·  1 ≤ Node.val ≤ 105

Try it yourself

Java
class Solution {
    public Node flatten(Node head) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
The flattened order is exactly a pre-order DFS (node, then its child list, then its next). It can be done without any stack: when a node has a child, find the child list's tail and splice the whole child list between the node and its next, then keep walking — deeper children get handled when the walk reaches them.
PatternLinked List Techniques

Instinct Nodes joined by next pointers and the task is to reverse, splice, merge, reorder or remove in place - grab a dummy head and rewire pointers carefully.

Memory hack Save next, flip, step - never let go of a rope before you've grabbed the next one.

Open the Linked List Techniques guide →

Approaches

Brute ForceCollect in DFS Order, Relink Everything

Time O(n)Space O(n)

Do a pre-order walk (node → child list → rest) and append each node to an ArrayList; reading all pointers first means nothing is lost. Then rewrite prev/next from the array and clear every child.

Java
public Node flatten(Node head) {
    List<Node> order = new ArrayList<>();
    collect(head, order);
    for (int i = 0; i < order.size(); i++) {
        Node n = order.get(i);
        n.child = null;
        n.prev = i > 0 ? order.get(i - 1) : null;
        n.next = i + 1 < order.size() ? order.get(i + 1) : null;
    }
    return head;
}

private void collect(Node node, List<Node> order) {
    for (Node c = node; c != null; c = c.next) {
        order.add(c);
        if (c.child != null) collect(c.child, order);
    }
}

Very hard to get wrong, but stores every node a second time.

At a glance

LevelApproachTimeSpace
Brute ForceCollect in DFS Order, Relink EverythingO(n)O(n)
BetterRecursive DFS Returning the TailO(n)O(depth)
OptimalIterative Splice (No Stack)O(n)O(1)
Common pitfalls
  • Forgetting child = null — the judge rejects a list that still has children.
  • Fixing next but not prev (both for the child head and the old next).
  • Losing the old next before splicing — save it first.
Interview tips
  • Rotate the picture 45°: it is a binary tree (child = left, next = right) and the answer is pre-order.
  • Mention the explicit-stack variant (push next, then child) as another O(n) option.
  • Test a child on the last node and a child-of-child chain.
Pattern
Pre-order flatten by splicing → turn nested / branching links into one list in place.
My notes saved in this browser