Description
Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target.
注意事项
- Given target value is a floating point.
- You are guaranteed to have only one unique value in the BST that is closest to the target.
样例
Given root = {1}
, target = 4.428571
, return 1
.
Solution
解法1:
先中序遍历存入ArrayList中,然后利用二分法找到排序数组中最接近的数(459. 排序数组中最接近元素)
解法2:
求出 lowerBound 和 upperBound。即 < target 的最大值和 >= target 的最小值。然后在两者之中去比较谁更接近,然后返回即可。
时间复杂度为 O(h)O(h),注意如果你使用 in-order traversal 的话,时间复杂度会是 o(n)o(n) 并不是最优的。另外复杂度也不是 O(logn)O(logn) 因为BST 并不保证树高是 logn 的。
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
* @param root: the given BST
* @param target: the given target
* @return: the value in the BST that is closest to the target
*/
public int closestValue(TreeNode root, double target) {
// write your code here
//算法很简单,求出 lowerBound 和 upperBound。
//即 < target 的最大值和 >= target 的最小值。
//然后在两者之中去比较谁更接近,然后返回即可。
//时间复杂度为 O(h)O(h),注意如果你使用 in-order traversal 的话
//时间复杂度会是 o(n)o(n) 并不是最优的。
//另外复杂度也不是 O(logn)O(logn) 因为BST 并不保证树高是 logn 的。
if (root == null) {
return 0;
}
//找到< target 的最大值和 >= target 的最小值。
TreeNode lowerNode = lowerBound(root, target);
TreeNode upperNode = upperBound(root, target);
//如果只有lowerBound 或 upperBound 之一,则直接返回
if (lowerNode == null) {
return upperNode.val;
}
if (upperNode == null) {
return lowerNode.val;
}
//在两者之中去比较谁更接近,然后返回即可
if (target - lowerNode.val > upperNode.val - target) {
return upperNode.val;
}
return lowerNode.val;
}
// find the node with the largest value that smaller than target
private TreeNode lowerBound(TreeNode root, double target) {
if (root == null) {
return null;
}
//如果根节点都大于等于target,则target一定在左子树
if (target <= root.val) {
return lowerBound(root.left, target);
}
//root.val < target
//否则target可能在右子树,也可能为根节点
TreeNode lowerNode = lowerBound(root.right, target);
if (lowerNode != null) {
return lowerNode;
}
return root;
}
// find the node with the smallest value that larger than or equal to target
private TreeNode upperBound(TreeNode root, double target) {
if (root == null) {
return null;
}
//如果根节点都小于target,则target一定在右子树
if (target > root.val) {
return upperBound(root.right, target);
}
// root.val >= target
//否则target可能在左子树,也可能为根节点
TreeNode upperNode = upperBound(root.left, target);
if (upperNode != null) {
return upperNode;
}
return root;
}
}