文章目录
- 摘要
- 描述
- 题解答案
- 题解代码分析
- 示例测试及结果
- 时间复杂度
- 空间复杂度
- 总结
摘要
在日常开发中,我们经常需要在一组有序的数据中快速找到最接近某个目标值的元素。LeetCode 第 270 题“Closest Binary Search Tree Value”正是这样一个问题。本文将深入解析该题,提供 Swift 语言的解题方案,并通过详细的代码分析和实际示例,帮助您掌握在二叉搜索树中高效查找最接近目标值的技巧。
描述
给定一个非空的二叉搜索树(BST)和一个目标值 target,找到 BST 中最接近 target 的值。如果有多个值同样接近 target,返回较小的那个。
示例:
输入:
root = [4,2,5,1,3], target = 3.714286
输出:
4
提示:
-
目标值是一个浮点数。
-
保证 BST 中只有一个最接近目标值的节点。
题解答案
我们可以利用二叉搜索树的特性,从根节点开始,根据目标值与当前节点值的大小关系,决定向左子树还是右子树搜索,同时记录当前最接近目标值的节点。
class Solution {
func closestValue(_ root: TreeNode?, _ target: Double) -> Int {
var closest = root!.val
var current = root
while let node = current {
if abs(Double(node.val) - target) < abs(Double(closest) - target) {
closest = node.val
}
if target < Double(node.val) {
current = node.left
} else {
current = node.right
}
}
return closest
}
}
题解代码分析
这段代码的核心思想是利用 BST 的性质进行二分搜索:
-
初始化:将
closest
初始化为根节点的值,current
指向根节点。 -
遍历:在遍历 BST 的过程中,比较当前节点的值与目标值的差距,如果更接近目标值,则更新
closest
。 -
方向选择:根据目标值与当前节点值的大小关系,决定向左子树还是右子树继续搜索。
这种方法的优势在于,它不需要遍历整个树,而是根据 BST 的特性,有选择地遍历部分节点,从而提高效率。
示例测试及结果
我们可以通过以下示例来测试上述代码的正确性:
// 构建示例 BST
let root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(5)
root.left?.left = TreeNode(1)
root.left?.right = TreeNode(3)
// 创建 Solution 实例
let solution = Solution()
// 测试
let result = solution.closestValue(root, 3.714286)
print("最接近的值是:\(result)") // 输出:4
在这个示例中,BST 的结构如下:
4
/ \
2 5
/ \
1 3
目标值为 3.714286,最接近的节点值是 4。
时间复杂度
-
最坏情况:O(n),当 BST 退化为链表时,需要遍历所有节点。
-
平均情况:O(log n),在平衡 BST 中,每次比较后可以排除一半的节点。
空间复杂度
- O(1),只使用了常数级别的额外空间。
总结
通过利用二叉搜索树的特性,我们可以高效地找到最接近目标值的节点。这种方法在处理有序数据结构时非常有用,特别是在需要快速查找接近某个值的元素时。在实际开发中,例如在推荐系统中查找最接近用户兴趣的内容,或在地图应用中查找最近的地点,都可以应用类似的思想。