題目: Given a binary search tree and a node in it, find the in-order successor of that node in the BST.
返回一棵BST中給定節點的中序遍歷後繼節點。就是在中序遍歷的順序中,給定點下一個要遍歷的點。
方法一:直觀邏輯
在BST中,進行二分搜索,找到所給節點,然後判斷:
1、所給節點p有右子節點,那麼後繼節點就是右子樹的最左節點。
2、所給節點是孩子節點,且之前有父節點,那麼依次取出父節點,直到某個n級的點是n-1級父節點的左子節點,那麼後繼節點就是n-1級父節點。
用一個棧記錄遍歷過的父節點,代碼如下:
public class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
return dfs(root, p, new Stack<>());
}
private TreeNode dfs(TreeNode root, TreeNode p, Stack<TreeNode> stack) {
if (root == null) return null;
TreeNode res;
if (p.val > root.val){
stack.push(root);
res = dfs(root.right, p, stack);
}
else if (p.val < root.val){
stack.push(root);
res = dfs(root.left, p, stack);
}
else {
if (root.right != null){
root = root.right;
while (root.left != null) root = root.left;
return root;
}else if (stack.isEmpty()) return null;
else {
TreeNode cur = root;
while (!stack.isEmpty()) {
if (stack.peek().left == cur) return stack.peek();
else cur = stack.pop();
}
return null;
}
}
return res;
}
}
方法二:分治思想
上面的代碼很複雜度還可以,但是實現十分的複雜,採用分治的思想,去分析每一個節點。
對於每一個節點,如果目標節點小於當前節點,那麼目標節點應該在左子樹,同時後繼節點可能由左子樹中產生,然而如果左子樹返回節點爲空,那麼後繼節點其實就是當前節點。
如果目標節點大於或者等於當前節點,後繼節點都一定在右子樹中。
可得代碼如下:
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;
}
}