|
5 | 5 |
|
6 | 6 | """ |
7 | 7 | # Definition for a Node. |
8 | | -class Node: |
| 8 | +class Node(object): |
9 | 9 | def __init__(self, val, prev, next, child): |
10 | 10 | self.val = val |
11 | 11 | self.prev = prev |
12 | 12 | self.next = next |
13 | 13 | self.child = child |
14 | 14 | """ |
15 | 15 |
|
16 | | -class Solution: |
17 | | - def flatten(self, head: 'Optional[Node]') -> 'Optional[Node]': |
| 16 | +class Solution(object): |
| 17 | + def flatten(self, head): |
18 | 18 | if not head: |
19 | | - return head # If the list is empty, just return |
| 19 | + return None # Return if the list is empty |
20 | 20 |
|
21 | | - def helper(curr): |
22 | | - """ |
23 | | - Recursively flattens the list starting from `curr`. |
24 | | - Returns the last node of the flattened list. |
25 | | - """ |
26 | | - last = curr # To track the tail of the flattened portion |
| 21 | + # Create a dummy node to simplify edge cases |
| 22 | + pseudoHead = Node(0, None, head, None) |
| 23 | + prev = pseudoHead |
27 | 24 |
|
28 | | - while curr: |
29 | | - tempNext = curr.next # Save next pointer in case we overwrite it |
| 25 | + stack = [head] # Use a stack for depth-first traversal |
30 | 26 |
|
31 | | - if curr.child: |
32 | | - # Save the child head |
33 | | - child_head = curr.child |
| 27 | + while stack: |
| 28 | + curr = stack.pop() # Pop the current node to process |
34 | 29 |
|
35 | | - # Recursively flatten the child list, returns the tail of the child chain |
36 | | - child_tail = helper(child_head) |
| 30 | + # Connect current node with the previous node |
| 31 | + prev.next = curr |
| 32 | + curr.prev = prev |
37 | 33 |
|
38 | | - # Splice the child list into the main list |
39 | | - curr.next = child_head # Connect current node to child head |
40 | | - child_head.prev = curr # Set child's prev to current |
41 | | - curr.child = None # Nullify the child pointer (as required) |
| 34 | + # If there is a next node, push it onto the stack. |
| 35 | + # It will be processed after the child node (if any) |
| 36 | + if curr.next: |
| 37 | + stack.append(curr.next) |
42 | 38 |
|
43 | | - # If there was a next node after current, attach it to the end of child list |
44 | | - if tempNext: |
45 | | - child_tail.next = tempNext |
46 | | - tempNext.prev = child_tail |
| 39 | + # If there is a child node, push it to the stack to be processed next |
| 40 | + # Set curr.child to None as it's flattened now |
| 41 | + if curr.child: |
| 42 | + stack.append(curr.child) |
| 43 | + curr.child = None # Important to remove child reference |
47 | 44 |
|
48 | | - # Update last to the end of the child list |
49 | | - last = child_tail |
| 45 | + # Move prev forward for the next iteration |
| 46 | + prev = curr |
50 | 47 |
|
51 | | - # Move current to the saved next pointer to continue flattening |
52 | | - curr = tempNext |
53 | | - else: |
54 | | - # No child, just move to next node |
55 | | - last = curr |
56 | | - curr = curr.next |
| 48 | + # Detach the pseudo head from the real head |
| 49 | + pseudoHead.next.prev = None |
| 50 | + return pseudoHead.next # Return the flattened list starting from the real head |
57 | 51 |
|
58 | | - return last # Return the tail of the fully flattened list |
59 | | - |
60 | | - helper(head) # Start recursive flattening from head |
61 | | - return head # Return head of flattened list |
0 commit comments