900 · Closest Binary Search Tree Value
Algorithms
Easy
Accepted Rate
54%
Description
Solution93
Notes
Discuss99+
Leaderboard
Record
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.
Example
Example1
Input: root = {5,4,9,2,#,8,10} and target = 6.124780
Output: 5
Explanation:
Binary tree {5,4,9,2,#,8,10}, denote the following structure:
5
/
4 9
/ /
2 8 10
Example2
Input: root = {3,2,4,1} and target = 4.142857
Output: 4
Explanation:
Binary tree {3,2,4,1}, denote the following structure:
3
/
2 4
/
1
我用的方法就是二分递归。当root->val > target时,结果只可能在root和左子树中选,否则就是在root和右子树中选。
注意!虽然pass了,但是还是有漏洞。关键在这一行
if (!root) return INT_MAX;
这里可能不对,因为如果某个节点为空,target是INT_MAX的话,INT_MAX就成了最佳结果了。
代码如下:
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: the given BST
* @param target: the given target
* @return: the value in the BST that is closest to the target
*/
int closestValue(TreeNode * root, double target) {
if (!root) return INT_MAX; //注意!这里可能不对,因为如果某个节点为空,target是INT_MAX的话,INT_MAX就成了最佳结果了。
double currGap=abs(root->val-target);
if (target>root->val) {
if (root->right) {
int rightCandidate = closestValue(root->right, target);
double rightGap=abs(rightCandidate - target);
if (rightGap<currGap)
return rightCandidate;
}
return root->val;
} else {
if (root->left) {
int leftCandidate = closestValue(root->left, target);
double leftGap=abs(leftCandidate - target);
if (leftGap<currGap)
return leftCandidate;
}
return root->val;
}
}
};
注意:下面的解法不对。因为当!root=0时,我们不能返回0。否则如果target是负数而二叉树的节点都是正数的话,这个0就是最佳结果了。但这是不对的,因为二叉树上没有0这个节点。所以下面的递归版上是根据kid是否为空来的,而不是根据root是否为空来的。
int closestValue(TreeNode *root, double target) {
if (!root) return 0; //这里不对!看看case {2, #, 3} target=-3
if (!root->left && !root->right) return root->val;
double rootAbsDiff = abs(root->val - target);
int closest = 0;
if (target < root->val) {
closest = closestValue(root->left, target);
} else {
closest = closestValue(root->right, target);
}
if (abs(closest - target) > abs(root->val - target)) {
closest = root->val;
}
return closest;
}
};
另外看到这个链接给出了简明扼要的递归和迭代两种解法,非常好。
http://rainykat.blogspot.com/2017/01/leetcode-270-closest-binary-search-tree.html
递归版:
public class Solution {
public int closestValue(TreeNode root, double target) {
// 选出子树的根节点
TreeNode kid = target < root.val ? root.left : root.right;
// 如果没有子树,也就是递归到底时,直接返回当前节点值
if(kid == null) return root.val; //注意!这一行很牛,包括了root节点没有子节点,和root节点的那个要递归的子节点为空的两种情况!
// 找出子树中最近的那个节点
int closest = closestValue(kid, target);
// 返回根节点和子树最近节点中,更近的那个节点
return Math.abs(root.val - target) < Math.abs(closest - target) ? root.val : closest;
}
}
迭代版:
We the node is in tree so traveling the BST and keep a value closet to target
Complexity: O(lgN)
public class Solution {
public int closestValue(TreeNode root, double target) {
int closest = root.val;
while(root!=null){
//if current root.val is closer, update closest
closest = Math.abs(closest-target)<Math.abs(root.val-target)?closest:root.val;
//do binary search
root = target<root.val?root.left:root.right;
}
return closest;
}
}
三刷: 前序遍历+二分。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: the given BST
* @param target: the given target
* @return: the value in the BST that is closest to the target
*/
int closestValue(TreeNode *root, double target) {
closest = root->val;
helper(root, target);
return closest;
}
private:
int closest = 0;
void helper(TreeNode *root, double target) {
if (!root) return;
//if (!root->left && !root->right) { //注意:这里不能加这行,要不然左右节点只有一个的情况就没有处理。
if (abs(root->val - target) < abs(closest - target)) closest = root->val;
// return;
//}
if (target < root->val) helper(root->left, target);
else helper(root->right, target);
return;
}
};
解法3:中序遍历。这个时间复杂度是O(h+k)。h是树的高度,k是返回的点是中序遍历的第几个点。这个算法太慢。不优。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: the given BST
* @param target: the given target
* @return: the value in the BST that is closest to the target
*/
int closestValue(TreeNode *root, double target) {
stack<TreeNode *> stk;
int res = root->val;
while (root || !stk.empty()) {
while (root) {
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
if (abs(root->val - target) < abs(res - target)) res = root->val;
root = root->right;
}
return res;
}
};
三刷
还是inorder traversal。注意光这么traversal的时间复杂度是O(n)。没有二分的好。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: the given BST
* @param target: the given target
* @return: the value in the BST that is closest to the target
*/
int closestValue(TreeNode *root, double target) {
closest = root->val;
helper(root, target);
return closest;
}
private:
int closest;
void helper(TreeNode *root, double target) {
if (!root) return;
helper(root->left, target);
if (abs(root->val - target) < abs(closest - target)) {
closest = root->val;
}
helper(root->right, target);
}
};
解法4:中序遍历+二分。
参考的labuladong的思路。这个方法很好!时间复杂度O(logn)。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: the given BST
* @param target: the given target
* @return: the value in the BST that is closest to the target
*/
int closestValue(TreeNode *root, double target) {
closest = root->val;
helper(root, target);
return closest;
}
private:
int closest;
void helper(TreeNode *root, double target) {
if (!root) return;
if (target < root->val) {
helper(root->left, target);
if (abs(root->val - target) < abs(closest - target)) {
closest = root->val;
}
} else {
if (abs(root->val - target) < abs(closest - target)) {
closest = root->val;
}
helper(root->right, target);
}
}
};