Problem
Given the root
of a binary tree, flatten the tree into a “linked list”:
- The “linked list” should use the same
TreeNode
class where theright
child pointer points to the next node in the list and theleft
child pointer is alwaysnull
. - The “linked list” should be in the same order as a pre-order traversal of the binary tree.
Examples
Example 1:
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like:
1
\
2
\
3
\
4
\
5
\
6
Input: root = [1,2,5,3,4,null,6]
Output: [1,null,2,null,3,null,4,null,5,null,6]
Note that the left child of all nodes should be NULL
.
Solution
Method 1 - Recursive
Preorder traversal makes things slightly easy for us, as root access easier since we start with the root. This is what we have to do:
- Process the root node first, as it is a preorder traversal. So, no changes required in root node
- Then we flatten the left subtree. How do we do it?
- Each time we see left subtree, we try to flatten it by putting it before right child:
- No change needed on right tree.
- Repeat the process : If we look at it, when we are the left side of the tree, we need to connect tail (or last node) in the left tree to connect to parent’s right child. So, in gist:
TreeNode temp = root.right;
root.right = leftList.head OR root.left;
leftList.tail = temp;
Code
Java
public void flatten(TreeNode root) {
dfs(root);
}
// helper function
private TreeNode dfs(TreeNode root) {
if (root == null) {
return null;
}
TreeNode leftTail = dfs(root.left);
TreeNode rightTail = dfs(root.right);
if(leftTail != null) {
leftTail.right = root.right;
root.right = root.left; // now root.left can be set to null
root.left = null;
}
return rightTail != null? rightTail: (leftTail!= null? leftTail: root)
}
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)
Method 2 - Iterative
Here are the steps we follow:
- Initialize
curr
to the root - Iterate through the tree - Continue the loop until all nodes have been processed, i.e.
curr
is null.- Process the left subtree - If the current node has a left child, we need to flatten the left subtree and reconnect links.
- Find the rightmost node of the left subtree, which is
leftTail
- Now, reassign pointers
- Connect the rightmost node of the left subtree (
leftTail
) to the right child ofcurr
(leftTail.right = curr.right
). - Move the left subtree to the right of
curr
(curr.right = curr.left
). - Set the left child of
curr
tonull
as required (curr.left = null
).
- Connect the rightmost node of the left subtree (
Code
Java
public void flatten(TreeNode root) {
TreeNode curr = root;
while (curr != null) {
if (curr.left != null) {
var leftTail = root.left;
while (leftTail.right != null)
leftTail = leftTail.right;
leftTail.right = curr.right;
curr.right = curr.left;
curr.left = null;
}
curr = curr.right;
}
}
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)