Given the root of a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus the sum of all keys greater than the original key in BST.
As a reminder, a binary search tree is a tree that satisfies these constraints:
Example 1:
Input: root = [4,1,6,0,2,5,7,null,null,null,3,null,null,null,8] Output: [30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
Example 2:
Input: root = [0,null,1] Output: [1,null,1]
Constraints:
[0, 104].-104 <= Node.val <= 104root is guaranteed to be a valid binary search tree.Note: This question is the same as 1038: https://leetcode.com/problems/binary-search-tree-to-greater-sum-tree/
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 goal is to change a tree so that each value also includes the sum of all values bigger than it. The brute force method figures this out by looking at each value separately and recalculating the sum of larger values every single time.
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 convert_bst_to_greater_tree_brute_force(root):
if not root:
return root
def get_all_node_values(root):
all_values = []
if root:
all_values.append(root.val)
all_values.extend(get_all_node_values(root.left))
all_values.extend(get_all_node_values(root.right))
return all_values
all_node_values = get_all_node_values(root)
def update_node_values(root, all_node_values):
if root:
original_node_value = root.val
greater_sum = 0
# Calculate the sum of all values greater than current node's value
for value in all_node_values:
if value > original_node_value:
greater_sum += value
root.val = original_node_value + greater_sum
update_node_values(root.left, all_node_values)
update_node_values(root.right, all_node_values)
update_node_values(root, all_node_values)
return rootThe key idea is to traverse the tree in a special order: right, node, left. While traversing, we keep track of a running sum of all the node values we've seen so far, and update each node's value with this sum.
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
class Solution:
def convertBST(self, root: TreeNode) -> TreeNode:
running_sum = 0
def traverse_right_node_left(root_node):
nonlocal running_sum
if not root_node:
return
# Traverse the right subtree first
traverse_right_node_left(root_node.right)
# Update running sum and node value
running_sum += root_node.val
root_node.val = running_sum
# Traverse the left subtree after updating the node
traverse_right_node_left(root_node.left)
#Start the traversal from the root.
traverse_right_node_left(root)
return root| Case | How to Handle |
|---|---|
| Null root | Return null immediately, as there's nothing to convert. |
| Single node tree | The node's value remains unchanged as there are no greater values to add. |
| Tree with all nodes having the same value | Each node will be updated to the tree's value times the number of nodes, due to iterative addition during the traversal. |
| Skewed tree (e.g., all nodes on the right side) | The rightmost node will keep its original value, and other node's value will be updated according to the right side values. |
| Skewed tree (e.g., all nodes on the left side) | All nodes will be updated with the cumulative sum of nodes from right to left. |
| Tree with negative values | The algorithm will handle negative values correctly, as it's based on summing the node values in reverse inorder traversal. |
| Integer overflow if node values are large | Consider using a larger integer type (e.g., long) or handling potential overflows to prevent incorrect sums. |
| Large BST causing stack overflow with recursive approach | Convert recursive solution to iterative approach using stack to avoid stack overflow |