题目描述
设计一个算法,找出二叉搜索树中指定节点的“下一个”节点(也即中序后继)。
如果指定节点没有对应的“下一个”节点,则返回null。
示例 1:
示例 2:
答案
我的答案
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<TreeNode> list = new ArrayList<>();
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
ldr(root,p);
for (int i = 0; i < list.size(); i++) {
if (list.get(i).val==p.val){
if (i+1==list.size()){
return null;
}else {
return list.get(i+1);
}
}
}
return null;
}
public void ldr(TreeNode root,TreeNode p){
if (root==null){
return;
}
ldr(root.left,p);
list.add(root);
ldr(root.right,p);
}
}
官方答案
中序遍历
思路
为了找到二叉搜索树中的节点 p 的后继节点,最直观的方法是中序遍历。由于只需要找到节点 p 的后继节点,因此不需要维护完整的中序遍历序列,只需要在中序遍历的过程中维护上一个访问的节点和当前访问的节点。如果上一个访问的节点是节点 p,则当前访问的节点即为节点 p 的后继节点。
如果节点 p 是最后被访问的节点,则不存在节点 p 的后继节点,返回 null。
代码
class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
TreeNode prev = null, curr = root;
while (!stack.isEmpty() || curr != null) {
while (curr != null) {
stack.push(curr);
curr = curr.left;
}
curr = stack.pop();
if (prev == p) {
return curr;
}
prev = curr;
curr = curr.right;
}
return null;
}
}
复杂度分析
-
时间复杂度:O(n),其中 n 是二叉搜索树的节点数。中序遍历最多需要访问二叉搜索树中的每个节点一次。
-
空间复杂度:O(n),其中 n 是二叉搜索树的节点数。空间复杂度取决于栈深度,平均情况是 O(logn),最坏情况是 O(n)。