# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
curr = root
while curr:
if curr.left:
# Find the rightmost node of left subtree
prev = curr.left
while prev.right:
prev = prev.right
# Rewire connections
prev.right = curr.right
curr.right = curr.left
curr.left = None
curr = curr.right
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
void flatten(TreeNode* root) {
TreeNode* curr = root;
while (curr) {
if (curr->left) {
// Find the rightmost node of left subtree
TreeNode* prev = curr->left;
while (prev->right) {
prev = prev->right;
}
// Rewire connections
prev->right = curr->right;
curr->right = curr->left;
curr->left = nullptr;
}
curr = curr->right;
}
}
};
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
class Solution {
public void flatten(TreeNode root) {
TreeNode curr = root;
while (curr != null) {
if (curr.left != null) {
// Find the rightmost node of left subtree
TreeNode prev = curr.left;
while (prev.right != null) {
prev = prev.right;
}
// Rewire connections
prev.right = curr.right;
curr.right = curr.left;
curr.left = null;
}
curr = curr.right;
}
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {void} Do not return anything, modify root in-place instead.
*/
var flatten = function(root) {
let curr = root;
while (curr) {
if (curr.left) {
// Find rightmost node in left subtree
let prev = curr.left;
while (prev.right) {
prev = prev.right;
}
// Rewire connections
prev.right = curr.right;
curr.right = curr.left;
curr.left = null;
}
curr = curr.right;
}
};
Given the root of a binary tree, you are to flatten the tree into a "linked list" in-place. The linked list should use the same TreeNode
structure, but every node's right
pointer should point to the next node in a pre-order traversal, and every node's left
pointer should be set to null
.
null
.The first step is to understand how a binary tree can be represented as a linked list using only the right pointers. Since the required order is pre-order traversal (root, left, right), we need to arrange the nodes so that each node's right pointer points to the next node in this traversal order.
A brute-force approach might involve performing a pre-order traversal, storing the nodes in a list, and then rewiring their left and right pointers accordingly. However, this would use extra space, which goes against the "in-place" requirement. To optimize, we need a way to rearrange the pointers as we traverse the tree, without using extra storage.
The key insight is that for each node with a left child, we can find the rightmost node of its left subtree and attach the current node's right subtree there. Then, we move the left subtree to the right and set the left pointer to null. This process can be repeated as we traverse the tree.
Let's work through an example with this tree:
1 / \ 2 5 / \ \ 3 4 6
1
. It has a left child (2
).
4
.1
's right subtree (5
) to 4
's right.2
) to 1
's right.1
's left to null.1 \ 2 / \ 3 4 \ 5 \ 6
2
. It has a left child (3
).
3
.2
's right subtree (4
) to 3
's right.3
) to 2
's right.2
's left to null.1 \ 2 \ 3 \ 4 \ 5 \ 6
3, 4, 5, 6
), but none have left children, so nothing changes.
O(N)
for traversal + O(N)
for rewiring = O(N)
O(N)
for storing nodes in a listO(N)
, since each node is visited and rewired at most once.O(1)
, as all modifications are done in-place and no extra data structures are used.The optimized approach is both time and space efficient, making it suitable for large trees.
To flatten a binary tree to a linked list in pre-order traversal, we iteratively rearrange pointers in-place. By always attaching the original right subtree to the rightmost node of the left subtree and moving the left subtree to the right, we ensure the correct order without using extra space. This approach is efficient, elegant, and leverages the structure of the binary tree for optimal pointer manipulation.