class Node:
    def __init__(self, val, prev=None, next=None, child=None):
        self.val = val
        self.prev = prev
        self.next = next
        self.child = child
class Solution:
    def flatten(self, head: 'Node') -> 'Node':
        def flatten_rec(node):
            curr = node
            last = node
            while curr:
                nxt = curr.next
                if curr.child:
                    child_head = curr.child
                    child_tail = flatten_rec(child_head)
                    curr.next = child_head
                    child_head.prev = curr
                    if nxt:
                        child_tail.next = nxt
                        nxt.prev = child_tail
                    curr.child = None
                    last = child_tail
                else:
                    last = curr
                curr = nxt
            return last
        flatten_rec(head)
        return head
      /*
// Definition for a Node.
class Node {
public:
    int val;
    Node* prev;
    Node* next;
    Node* child;
};
*/
class Solution {
public:
    Node* flatten(Node* head) {
        flattenDFS(head);
        return head;
    }
    
    Node* flattenDFS(Node* node) {
        Node* curr = node;
        Node* last = node;
        while (curr) {
            Node* nxt = curr->next;
            if (curr->child) {
                Node* child_head = curr->child;
                Node* child_tail = flattenDFS(child_head);
                curr->next = child_head;
                child_head->prev = curr;
                if (nxt) {
                    child_tail->next = nxt;
                    nxt->prev = child_tail;
                }
                curr->child = nullptr;
                last = child_tail;
            } else {
                last = curr;
            }
            curr = nxt;
        }
        return last;
    }
};
      /*
// Definition for a Node.
class Node {
    public int val;
    public Node prev;
    public Node next;
    public Node child;
};
*/
class Solution {
    public Node flatten(Node head) {
        flattenDFS(head);
        return head;
    }
    
    private Node flattenDFS(Node node) {
        Node curr = node;
        Node last = node;
        while (curr != null) {
            Node nxt = curr.next;
            if (curr.child != null) {
                Node childHead = curr.child;
                Node childTail = flattenDFS(childHead);
                curr.next = childHead;
                childHead.prev = curr;
                if (nxt != null) {
                    childTail.next = nxt;
                    nxt.prev = childTail;
                }
                curr.child = null;
                last = childTail;
            } else {
                last = curr;
            }
            curr = nxt;
        }
        return last;
    }
}
      /**
 * // Definition for a Node.
 * function Node(val, prev, next, child) {
 *     this.val = val;
 *     this.prev = prev;
 *     this.next = next;
 *     this.child = child;
 * };
 */
/**
 * @param {Node} head
 * @return {Node}
 */
var flatten = function(head) {
    function flattenDFS(node) {
        let curr = node;
        let last = node;
        while (curr) {
            let nxt = curr.next;
            if (curr.child) {
                let childHead = curr.child;
                let childTail = flattenDFS(childHead);
                curr.next = childHead;
                childHead.prev = curr;
                if (nxt) {
                    childTail.next = nxt;
                    nxt.prev = childTail;
                }
                curr.child = null;
                last = childTail;
            } else {
                last = curr;
            }
            curr = nxt;
        }
        return last;
    }
    flattenDFS(head);
    return head;
};
      You are given the head of a multilevel doubly linked list. Each node in this list contains:
valprev and next to the previous and next nodes, respectivelychild pointer that may point to another doubly linked list (the child list)
    Your task is to flatten the list so that all nodes appear in a single-level, doubly linked list. The nodes should appear in a depth-first order: for each node, after itself, its child list (if any) should be inserted before its next node. All child pointers must be set to null in the flattened list.
  
Constraints:
When approaching this problem, the first idea that might come to mind is to traverse the list and, whenever a node has a child, insert the entire child list between the current node and its next node. This requires careful pointer manipulation to preserve the doubly linked nature and not lose track of the rest of the list.
A brute-force approach could be to collect all the nodes in a flat array, then reconstruct the list. However, this would violate the constraints of not using extra data structures and not creating new nodes.
Therefore, we need an in-place algorithm. The recursive nature of the multilevel structure suggests that a depth-first traversal would be effective. At each node, we process its child (if present) before moving to the next node. This way, we can "splice" the child list into the main list at the correct position.
    The challenge is to keep track of the tail of the flattened child list so we can reconnect the next node properly. We also need to ensure that all child pointers are set to null after flattening.
  
The solution uses a recursive depth-first traversal to flatten the multilevel doubly linked list in place. Here’s a step-by-step breakdown:
next pointer to the child, and set the child’s prev to the current node.next node, connect the tail of the child list to it, and set the next node’s prev to the child list’s tail.child pointer to null.This method ensures all nodes are visited exactly once, and all pointers are updated in place, without extra data structures.
Consider the following multilevel list:
Step-by-step:
The final flattened list is: 1-2-3-7-8-11-12-9-10-4-5-6
Brute-force approach:
No additional data structures are used beyond the recursion stack.
The problem of flattening a multilevel doubly linked list is elegantly solved using a recursive, depth-first traversal. The key insight is to process each child list in place, splicing it into the main list and updating all pointers as you go. This method respects all constraints: it does not use extra space (apart from the call stack), does not create new nodes, and guarantees the unique, correct order for the flattened list. The approach is efficient, easy to reason about, and leverages the recursive structure of the input data.