本文详细解析LeetCode第285题"二叉搜索树中的顺序后继",这是一道考察二叉搜索树性质的中等难度题目。文章提供了递归和迭代两种实现方案,包含C#、Python、C++三种语言实现,配有详细的树遍历分析和性能对比。适合学习二叉搜索树和树遍历算法的读者。
核心知识点: 二叉搜索树、中序遍历、树的遍历
难度等级: 中等
推荐人群: 具备基础数据结构知识,想要提升树算法设计能力的开发者
给定一棵二叉搜索树和其中的一个节点 p ,找到该节点在树中的中序后继。如果节点没有中序后继,请返回 null 。
节点 p 的后继是值比 p.val 大的节点中值最小的节点。
输入:root = [2,1,3], p = 1
输出:2
解释:这里 1 的中序后继是 2。请注意 p 和返回值都应是 TreeNode 类型。
输入:root = [5,3,6,2,4,null,null,1], p = 6
输出:null
解释:因为给出的节点没有中序后继,所以答案就返回 null 。
[1, 10^4]
内。-10^5 <= Node.val <= 10^5
本题可以使用两种方法来实现:
利用BST性质:
中序遍历:
当前节点值 | 与p的关系 | 搜索方向 | 可能是后继 |
---|---|---|---|
root.val <= p.val | 小于等于 | 右子树 | 否 |
root.val > p.val | 大于 | 左子树 | 是 |
遍历顺序 | 当前节点 | 前一节点 | 是否找到p | 操作 |
---|---|---|---|---|
左子树 | null | null | 否 | 继续遍历 |
根节点 | root | prev | 是/否 | 更新prev |
右子树 | next | root | 是/否 | 继续遍历 |
public class Solution {
public TreeNode InorderSuccessor(TreeNode root, TreeNode p) {
TreeNode successor = null;
while (root != null) {
if (p.val >= root.val) {
root = root.right;
} else {
successor = root;
root = root.left;
}
}
return successor;
}
}
class Solution:
def inorderSuccessor(self, root: TreeNode, p: TreeNode) -> TreeNode:
successor = None
while root:
if p.val >= root.val:
root = root.right
else:
successor = root
root = root.left
return successor
class Solution {
public:
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
TreeNode* successor = nullptr;
while (root != nullptr) {
if (p->val >= root->val) {
root = root->right;
} else {
successor = root;
root = root->left;
}
}
return successor;
}
};
语言 | 执行用时 | 内存消耗 | 特点 |
---|---|---|---|
C# | 88 ms | 27.2 MB | 代码结构清晰,性能适中 |
Python | 76 ms | 18.6 MB | 代码最简洁,性能不错 |
C++ | 28 ms | 22.8 MB | 性能最优,内存占用适中 |
解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
---|---|---|---|---|
BST性质法 | O(H) | O(1) | 空间效率高 | 依赖BST性质 |
中序遍历法 | O(N) | O(H) | 思路直观 | 需要遍历全树 |
父指针法 | O(H) | O(1) | 实现简单 | 需要父指针 |
算法专题合集 - 查看完整合集
关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新第285题。
感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。
如果这篇文章对你有帮助,请:
你的支持是我持续分享的动力!
一起进步:算法学习路上不孤单,欢迎一起交流学习!