[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 isnull
.
Note:
- If the given node has no in-order successor in the tree, return
null
. - 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 };
相关题目