This problem involves rerooting a binary tree, where a given leaf node becomes the new root. The process involves iterating from the leaf node up to the original root, modifying parent-child relationships at each step.
Algorithm:
The solution uses an iterative approach. It starts at the given leaf
node and iteratively moves towards the original root
. In each iteration, it performs the following steps:
Handle the right child: If the current node (cur
) has a left child, this child becomes the right child of cur
. This step ensures the right subtree is preserved.
Change parent-child links: The current node's parent (p
) becomes the left child of cur
. The parent-child link between p
and cur
is broken.
Null out parent's child: We check if p
was the parent of cur
as a left or right child and set the appropriate child pointer to null
in p
. This avoids dangling references and ensures the tree structure remains consistent.
Move up the tree: The pointers cur
and p
are updated to continue the process up to the original root.
Set the new root's parent to null: Finally, the parent of the new root (leaf
) is set to null
.
Time Complexity: O(H), where H is the height of the tree. In the worst case (a skewed tree), the algorithm iterates through all nodes from the leaf to the root.
Space Complexity: O(1). The algorithm uses only a constant amount of extra space to store variables.
Code Explanation (Python):
class Solution:
def flipBinaryTree(self, root: "Node", leaf: "Node") -> "Node":
cur = leaf
p = cur.parent
while cur != root:
gp = p.parent #Grandparent needed to move up correctly
if cur.left:
cur.right = cur.left
cur.left = p
p.parent = cur
if p.left == cur:
p.left = None
elif p.right == cur:
p.right = None
cur = p
p = gp
leaf.parent = None
return leaf
The Python code directly implements the algorithm described above. The while
loop continues until the current node (cur
) reaches the original root. Inside the loop, the steps to handle the right child, change parent-child links, null out parent's child, and move up the tree are performed. The use of gp
(grandparent) is crucial for correctly traversing up the tree.
The other languages (Java, C++, JavaScript, C#) follow a very similar structure, adapting syntax to their respective languages but maintaining the same algorithmic approach. The core logic remains consistent across all implementations.