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:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
Each node should become the sum of all keys not smaller than itself. In a BST those keys are exactly the nodes already seen in reverse inorder.
Walk right-root-left, accumulate into \(s\), and write \(s\) back. The right subtree is processed first, so larger keys are already included. One traversal.
1 2 3 4 5 6 7 8 91011121314151617181920
# 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 = rightclassSolution:defconvertBST(self,root:TreeNode)->TreeNode:defdfs(root):nonlocalsifrootisNone:returndfs(root.right)s+=root.valroot.val=sdfs(root.left)s=0dfs(root)returnroot
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */funcconvertBST(root*TreeNode)*TreeNode{s:=0vardfsfunc(*TreeNode)dfs=func(root*TreeNode){ifroot==nil{return}dfs(root.Right)s+=root.Valroot.Val=sdfs(root.Left)}dfs(root)returnroot}
Recursive reverse inorder uses an \(O(h)\) stack. Morris temporarily links a node's inorder predecessor (leftmost of the right subtree) to recover the parent without a stack.
Thread when going right, accumulate and write on the return visit, then unthread and go left. The order is still right-root-left, with constant extra space.
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */funcconvertBST(root*TreeNode)*TreeNode{s:=0node:=rootforroot!=nil{ifroot.Right==nil{s+=root.Valroot.Val=sroot=root.Left}else{next:=root.Rightfornext.Left!=nil&&next.Left!=root{next=next.Left}ifnext.Left==nil{next.Left=rootroot=root.Right}else{s+=root.Valroot.Val=snext.Left=nilroot=root.Left}}}returnnode}