Given a binary search tree and a node in it, find the in-order successor of that node in the BST.
Note: If the given node has no in-order successor in the tree, return null.
Solution1:Iterative: binary search + prev
[实现巧妙]
1_a: Find Inorder Predecessor: BST中Inorder前驱一定比p小,所以是在p的左子树里的最大值,所以当找到p后向左一次继续再向右到底。要没有,就是p的祖先中的最近一次向右的(通过keep prev,向右子树找的时候才拖着"更新"prev尾巴,向左时keep prev)
1_b: Find Inorder Successor: BST中Inorder后继一定比p大,所以是在p的右子树里的最小值,所以当找到p后向右一次继续再向左到底。要没有,就是p的祖先中的最近一次向右的的(通过keep prev,向左子树找的时候才拖着"更新"prev尾巴,向右时keep prev)
思路:
Time Complexity: O(N) Space Complexity: O(1)
Solution2:Recursive: binary serach
2_a: Find Inorder Predecessor
2_b: Find Inorder Successor:
by jeantimex : let's take the successor for example, basically we always want to find p's closest node (in inorder traversal) and the node's value is larger than p's value, right? That node can either be p's parent or the smallest node in p' right branch.
When the code runs into the else block, that means the current root is either p's parent or a node in p's right branch.
If it's p's parent node, there are two scenarios: 1. p doesn't have right child, in this case, the recursion will eventually return null, so p's parent is the successor; 2. p has right child, then the recursion will return the smallest node in the right sub tree, and that will be the answer.
If it's p's right child, there are two scenarios: 1. the right child has left sub tree, eventually the smallest node from the left sub tree will be the answer; 2. the right child has no left sub tree, the recursion will return null, then the right child (root) is our answer.
Time Complexity: O(N) Space Complexity: O(N) 递归缓存
Solution1_a Code: Find Inorder Predecessor
class Solution {
public TreeNode inorderPredecessor(TreeNode root, TreeNode p) {
TreeNode cur = root;
TreeNode prede = null;
while (cur != null) {
if(p.val == cur.val) cur = cur.left;
else if (p.val > cur.val) {
// turn right
prede = cur;
cur = cur.right;
}
else cur = cur.left;
}
return prede;
}
}
Solution1_b Code: Find Inorder Successor
class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
TreeNode cur = root;
TreeNode succ = null;
while (cur != null) {
if(p.val == cur.val) cur = cur.right;
else if (p.val < cur.val) {
// turn left
succ = cur;
cur = cur.left;
}
else cur = cur.right;
}
return succ;
}
}
Solution2_a Code: Find Inorder Predecessor
public TreeNode predecessor(TreeNode root, TreeNode p) {
if (root == null)
return null;
if (root.val >= p.val) {
return predecessor(root.left, p);
} else {
TreeNode right = predecessor(root.right, p);
return (right != null) ? right : root;
}
}
Solution2_b Code: Find Inorder Successor
public TreeNode successor(TreeNode root, TreeNode p) {
if (root == null)
return null;
if (root.val <= p.val) {
return successor(root.right, p);
} else {
TreeNode left = successor(root.left, p);
return (left != null) ? left : root;
}
}