大家好,我是 @负雪明烛。👈👈 点击关注,优质题解不间断。

题目大意

找出二叉搜索树中,比指定节点大的下一个节点。

解题方法

思路

二叉搜索树的定义:

  1. 左子树都比当前节点的值小;
  2. 右子树都比当前节点的值大。

我们要找比指定节点p大的下一个节点的,那么有以下可能:

  1. 当前节点的值 <= 指定节点的值,即 面试题 04.06. 后继者 - 图1,那么一定要在面试题 04.06. 后继者 - 图2的右子树上找比 面试题 04.06. 后继者 - 图3大的下一个节点。

    因为我们要找比 p大的节点,而此时 面试题 04.06. 后继者 - 图4和其左子树都比 面试题 04.06. 后继者 - 图5小,因此左子树上就不用找了。

当然如果右子树不存在,那么也就找不到结果,返回 面试题 04.06. 后继者 - 图6

  1. 当前节点的值 > 指定节点的值,即 面试题 04.06. 后继者 - 图7,那么比 面试题 04.06. 后继者 - 图8大的节点可能在 面试题 04.06. 后继者 - 图9的左子树上,也可能就是 $root$。

我们先尝试在 面试题 04.06. 后继者 - 图10的左子树中寻找比 面试题 04.06. 后继者 - 图11大的下一个节点,如果能找到,那么就是结果。

否则当前的 面试题 04.06. 后继者 - 图12 是结果。

递归

在上面的思路中,我们提到了「在左/右子树寻找比 面试题 04.06. 后继者 - 图13大的下一个节点」,这恰好和题目中所定义的函数 inorderSuccessor(TreeNode* root, TreeNode* p)的意义是一样的,因此我们可以使用「递归」。

从这里也能看出来,我们并不是为了「递归」而「递归」,而是我们把「大问题」拆分成了「小问题」。大、小问题只有数据规模不同,但是都可以用同样的方法处理,因此形成了「递归」。

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
  13. if (!root) return nullptr;
  14. if (root->val <= p-> val)
  15. return inorderSuccessor(root->right, p);
  16. TreeNode* findLeft = inorderSuccessor(root->left, p);
  17. return findLeft ? findLeft : root;
  18. }
  19. };

复杂度

  • 时间复杂度:最差为 $O(N)$,面试题 04.06. 后继者 - 图14是二叉搜索树的节点数。
  • 空间复杂度:$O(1)$,没用额外空间。

    总结

  1. 二叉搜索树的题目都是套路题目,要么是根据左右子树的大小性质(比如本题),要么考察中序遍历。



我是 @负雪明烛 ,刷算法题 1000 多道,写了 1000 多篇算法题解,收获阅读量 300 万。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。