Given the root
of a binary tree, turn the binary tree upside down and return the new root.
You can turn a binary tree upside down with the following steps:
The mentioned steps are performed in-place.
Example 1:
Input: root = [1,2,3,4,5]
Output: [4,5,2,null,null,3,1]
Example 2:
Input: root = []
Output: []
Example 3:
Input: root = [1]
Output: [1]
Constraints:
[0, 10]
.1 <= Node.val <= 10
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to flipping a binary tree upside down involves exploring all possible reconfigurations by rearranging the connections between the nodes. We essentially examine every possible upside-down version of the tree.
Here's how the algorithm would work step-by-step:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def upside_down_binary_tree_brute_force(root):
current_node = root
previous_right = None
parent = None
while current_node:
# Store the left node, since we'll change its reference
next_left = current_node.left
# The new root's left child becomes the original root
current_node.left = previous_right
# The new root's right child is the original root's parent
previous_right = current_node.right
current_node.right = parent
parent = current_node
current_node = next_left
return parent
The core idea is to repeatedly transform the tree from the bottom-left up. We iteratively rewire the nodes to achieve the upside-down transformation. This is done by updating the left, right, and parent pointers of the nodes.
Here's how the algorithm would work step-by-step:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def upside_down_binary_tree(root):
current_node = root
previous_right_node = None
parent_node = None
while current_node:
# Store the left and right nodes
left_node = current_node.left
right_node = current_node.right
# The leftmost node becomes the new root
current_node.left = previous_right_node
# The current node becomes the left child of the node above
current_node.right = parent_node
# Update variables to move up one level
previous_right_node = right_node
parent_node = current_node
current_node = left_node
return parent_node
Case | How to Handle |
---|---|
Null root input | Return null immediately; an empty tree upside-down is still empty. |
Single node tree | Return the original root node as it is already 'upside down'. |
Tree with only left children (no right children) | The algorithm should correctly re-wire the left-leaning tree into its upside-down equivalent, handling null right children gracefully. |
Perfectly balanced binary tree | The algorithm must correctly invert the structure while maintaining the parent-child relationships in the correct inverted order. |
Skewed tree (left or right) | Ensure algorithm transforms the skewed tree accurately without losing any nodes and maintaining the new structure's integrity. |
Tree with duplicate values | Duplicate values do not inherently affect the algorithm's logic as it focuses on structural transformation, not value uniqueness. |
Very large tree (potential stack overflow with recursion) | Consider an iterative solution to avoid potential stack overflow issues in cases of extremely deep trees. |
Tree violating the sibling constraint (right node not a leaf or without a sibling) | State in the prompt that we assume the input tree follows the constraint, so it's not strictly an 'edge' case that needs specific handling, just valid input. |