We need to rearrange a binary tree so that it becomes a right-skewed "linked list" using the existing TreeNode structure. Every node's left child must be null, and its right child must point to the next node in pre-order sequence. Pre-order means root, then left subtree, then right subtree.
The difficulty is doing this restructuring without losing access to subtrees while rewiring pointers. Setting node.right = node.left directly discards the original right subtree before we have visited it. The whole problem is about preserving that right subtree until it has been linked in.
Number of nodes in range [0, 2000]: With at most 2,000 nodes, even an O(n^2) solution runs in time, so the work is getting the pointer manipulation correct rather than minimizing operations.Node values are irrelevant to the logic. We are rearranging pointers, not reading values.
A pre-order traversal visits the nodes in exactly the order they must appear in the flattened list. If we collect every node into a list during that traversal, we already have the final ordering. The second pass walks the list and rewires each node so its left is null and its right points to the next node.
This separates the two concerns. The traversal decides the order, and the rewiring never has to worry about losing a subtree because the list already holds a reference to every node. The cost is O(n) extra space for the list.
node.left = null.node.right = list[i + 1] (or null for the last node).The next approach removes the explicit list by rewiring pointers during the traversal itself.
If we process the tree in reverse pre-order (right subtree, then left subtree, then root), the order in which nodes are processed is exactly the reverse of the flattened list. We keep a running pointer prev that holds the previously processed node, which is the node that should come right after the current one. When we process the current node, we set current.right = prev, set current.left = null, then update prev = current.
The ordering is what makes this safe. Pre-order is root, left subtree, right subtree. Reversing it gives right subtree, left subtree, root. The first node processed is the last node of the flattened list, and the last node processed (the root) is the first. Because every node's successor is processed before the node itself, prev always holds the correct next pointer by the time we wire the current node.
This is the same construction as building a singly linked list by prepending. Insert elements in reverse order and the list reads forward correctly, with no need to track a tail pointer. Here prev plays the role of the list head: each node is prepended by pointing its right at the current head and then becoming the new head.
prev to null.node.right first.node.left.node.right = prev and node.left = null.prev = node.This removes the list but still uses O(h) stack space from recursion. The next approach flattens the tree iteratively in O(1) space.
This is the approach the follow-up asks for. It adapts Morris traversal, which walks a tree without recursion or a stack by temporarily rewiring pointers.
For each node that has a left subtree, the entire left subtree has to move to the right side. Overwriting node.right directly would discard the original right subtree. The fix is to attach the original right subtree to the end of the left subtree before moving anything: find the rightmost node of the left subtree and point its right at the original right subtree. After that, moving the left subtree into node.right keeps every node reachable, because walking to the end of the relocated left subtree leads straight into the old right subtree.
The pre-order property follows from this. After the move, node.right is the old left subtree (the nodes that come next in pre-order), and the old right subtree hangs off the rightmost end of it (the nodes that come after the entire left subtree). Advancing current down the right pointers then revisits each node and repeats the same fix where needed.
current = root.current is not null:current has a left child: a. Find the rightmost node of the left subtree (call it predecessor).
b. Set predecessor.right = current.right (stitch the right subtree).
c. Set current.right = current.left (move left subtree to the right).
d. Set current.left = null (clear the left pointer).
current = current.right.