Given the root of a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that shares the same parent) or empty, flip the tree upside down and return the new root.
In the upside-down version of the binary tree:
The transformation should be done in-place, and you must not create new nodes or reuse values. There is exactly one valid solution for each input tree.
At first glance, the problem seems to ask for a "rotation" of the binary tree, but it is more specific: for each subtree, the leftmost node becomes the new root, and each parent moves down to the right. The right child of any node becomes the left child of its parent in the new tree.
A brute-force approach would involve traversing the tree, collecting nodes, and reconstructing a new tree. However, the constraints require us to do this in-place, without creating new nodes.
To optimize, we notice that we can process the tree recursively (or iteratively), always focusing on the leftmost path. As we return from recursion, we rewire pointers, making the original parent the new right child and the original right child the new left child at each step.
The solution can be implemented either recursively or iteratively. The recursive approach is more intuitive, as it naturally follows the leftmost path down to the new root, then rewires pointers as the call stack unwinds.
null
or has no left child, it becomes the new root.
null
to avoid cycles.
The iterative approach follows a similar logic, but uses a loop to traverse down the leftmost path, rewiring pointers at each step.
Consider the following binary tree:
1 / \ 2 3 / \ 4 5
Let's walk through the process:
null
.4 / \ 5 2 / \ 3 1
The optimized approach is efficient and meets the problem's in-place constraint.
The "Binary Tree Upside Down" problem requires flipping a binary tree so the leftmost node becomes the new root, and the parent and right child are repositioned as right and left children, respectively. The in-place recursive (or iterative) solution elegantly walks down the leftmost path, rewires pointers as it unwinds, and meets both time and space efficiency requirements. This approach leverages the structure of the tree and pointer manipulation, making it both efficient and intuitive once understood.
# 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 upsideDownBinaryTree(self, root: TreeNode) -> TreeNode:
if not root or not root.left:
return root
newRoot = self.upsideDownBinaryTree(root.left)
root.left.left = root.right
root.left.right = root
root.left = None
root.right = None
return newRoot
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
TreeNode* upsideDownBinaryTree(TreeNode* root) {
if (!root || !root->left) return root;
TreeNode* newRoot = upsideDownBinaryTree(root->left);
root->left->left = root->right;
root->left->right = root;
root->left = nullptr;
root->right = nullptr;
return newRoot;
}
};
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
public TreeNode upsideDownBinaryTree(TreeNode root) {
if (root == null || root.left == null) return root;
TreeNode newRoot = upsideDownBinaryTree(root.left);
root.left.left = root.right;
root.left.right = root;
root.left = null;
root.right = null;
return newRoot;
}
}
// 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)
}
var upsideDownBinaryTree = function(root) {
if (!root || !root.left) return root;
let newRoot = upsideDownBinaryTree(root.left);
root.left.left = root.right;
root.left.right = root;
root.left = null;
root.right = null;
return newRoot;
};