[LeetCode] 285. Inorder Successor in BST

Given a binary search tree and a node in it, find the in-order successor of that node in the BST.

The successor of a node p is the node with the smallest key greater than p.val.

Example 1:

Input: root = [2,1,3], p = 1
Output: 2
Explanation: 1's in-order successor node is 2. Note that both p 
and the return value is of TreeNode type.

Example 2:

Input: root = [5,3,6,2,4,null,null,1], p = 6
Output: null
Explanation: There is no in-order successor of the current 
node, so the answer is null.

Note:

  1. If the given node has no in-order successor in the tree, return null.
  2. It's guaranteed that the values of the tree are unique.

二叉搜索树中的中序后继。

题意是给一个二叉搜索树和一个节点,请返回这个节点中序遍历的下一个节点。

既然题目都讲明了是中序遍历所以记住重点是遍历下来的结果,一个是递增的,一个是遍历的顺序是左 - 根 - 右。比较粗暴的做法就是像94题那样迭代用 stack 遍历所有的节点,用一个变量 pre 记住前一个节点。同时当我们从 stack 中不断弹出节点的时候,如果发现前一个节点是P的话,当前的 cur 节点就是我们要找的节点。这个做法会用到额外的空间。

时间O(n)

空间O(n)

Java实现

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution {
11     public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
12         List<TreeNode> res = new ArrayList<>();
13         // corner case
14         if (root == null) {
15             return null;
16         }
17         // normal case
18         Stack<TreeNode> stack = new Stack<>();
19         TreeNode pre = null;
20         TreeNode cur = root;
21         while (cur != null || !stack.isEmpty()) {
22             while (cur != null) {
23                 stack.push(cur);
24                 cur = cur.left;
25             }
26             cur = stack.pop();
27             if (pre != null) {
28                 if (pre.val == p.val) {
29                     return cur;
30                 }
31             }
32             pre = cur;
33             res.add(cur);
34             cur = cur.right;
35         }
36         return null;
37     }
38 }

我这里再给出一个不使用额外空间的迭代写法。如果根节点不为空,判断节点 p 跟 root 的大小关系,如果 p 较小,说明 root 有可能就是 p 的中序后继(中序遍历的后继节点一定相对更大,同时万一 p 节点自己是没有右孩子的话,那么 p 的后继节点就会是 root),将 root 赋给 res,往左子树走;如果 p 较大,p 的中序后继也只会是在 root 的右边,所以往右走。但有可能 p 是树中最大的节点,所以只往右子树走即可,不需要其他动作。

给一个更好的例子吧(见下图),如果找的 p 是 35,因为比根节点 25 大,所以一开始就只能往右子树走,root = 50;再跟 50 判断,因为 35 比 50 小所以把 50 赋给 res,此时 50 有可能就是要找的节点,并同时往左子树走,root = 35;此时因为 root = 35 <= p 所以又得往右走,root = 44;下一轮44 > 35了所以把44赋给res;最后一轮 root 为空了,直接跳出 while 循环,得到 res = 44。

时间O(n)

空间O(1)

Java实现

 1 class Solution {
 2     public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
 3         if (root == null) {
 4             return null;
 5         }
 6         TreeNode res = null;
 7         while (root != null) {
 8             if (root.val > p.val) {
 9                 res = root;
10                 root = root.left;
11             } else {
12                 root = root.right;
13             }
14         }
15         return res;
16     }
17 }

JavaScript实现

 1 /**
 2  * @param {TreeNode} root
 3  * @param {TreeNode} p
 4  * @return {TreeNode}
 5  */
 6 var inorderSuccessor = function (root, p) {
 7     if (root == null) {
 8         return null;
 9     }
10     let res = null;
11     while (root != null) {
12         if (root.val > p.val) {
13             res = root;
14             root = root.left;
15         } else {
16             root = root.right;
17         }
18     }
19     return res;
20 };

相关题目

285. Inorder Successor in BST

510. Inorder Successor in BST II

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/12530798.html