题目链接:
力扣https://leetcode.cn/problems/successor-lcci/
【方法一 中序遍历】直接中序遍历保存所有节点的路径,然后遍历节点找后继。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public ArrayList<TreeNode> list = new ArrayList();
public void dfs(TreeNode node){
if(node == null) return;
dfs(node.left);
list.add(node);
dfs(node.right);
}
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
dfs(root);
list.add(null);
int n = list.size() - 1;
for(var i = 0; i < n; i++){
if(list.get(i) == p) return list.get(i + 1);
}
return null;
}
}
简化一下存储结构
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
boolean is = false;
TreeNode ans = null;
TreeNode p;
public void dfs(TreeNode node){
if(node == null) return;
dfs(node.left);
if(is && ans == null) {
ans = node;
}
if(node == p) is = true;
dfs(node.right);
}
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
this.p = p;
dfs(root);
return ans;
}
}
【方法二 利用BST的性质】如果节点p的右节点不为空,那么后继肯定在右节点上,而且是右节点的最左下角的那个;否则,后继是在p的父节点,那么就需要从root开始遍历了,如果root.val<=p.val,那么后继肯定在root的右边;如果root.val>p.val,那么root可能是要找的节点,但是不一定是最小的那个,所以赋值给ans后还要继续递归寻找。
class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
TreeNode ans = null;
if(p.right != null){
p = p.right;
ans = p;
while(p.left!= null){
ans = p.left;
p = p.left;
}
return ans;
}else{
while(root != null){
if(root.val <= p.val){
root = root.right;
}else{
ans = root;
root = root.left;
}
}
return ans;
}
}
}