901 · Closest Binary Search Tree Value II
Algorithms
Hard
Accepted Rate
49%
Description
Solution75
Notes99+
Discuss3
Leaderboard
Record
Description
Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.
Given target value is a floating point.
You may assume k is always valid, that is: k ≤ total nodes.
You are guaranteed to have only one unique set of k values in the BST that are closest to the target.
Example
Example 1:
Input:
{1}
0.000000
1
Output:
[1]
Explanation:
Binary tree {1}, denote the following structure:
1
Example 2:
Input:
{3,1,4,#,2}
0.275000
2
Output:
[1,2]
Explanation:
Binary tree {3,1,4,#,2}, denote the following structure:
3
/
1 4
2
Challenge
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?
Tags
Company
Google
Related Problems
67
Binary Tree Inorder Traversal
Easy
900
Closest Binary Search Tree Value
Easy
解法1:
思路是通过中序遍历得到BST的无下降序列,然后用双向双指针得到中间的k个数。这个方法好!
代码如下:
注意:
1)双向双指针的用法(这里是查找k个数的window!)
/**
* 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
* @param k: the given k
* @return: k values in the BST that are closest to the target
*/
vector<int> closestKValues(TreeNode * root, double target, int k) {
vector<int> nums = inOrderTraversal(root);
int i = 0, j = nums.size()-1;
while(j - i > k - 1) {
if (abs(nums[i] - target) <= abs(nums[j] - target)) {
j--;
} else {
i++;
}
}
vector<int> result;
for (int m = i; m <= j; m++) {
result.push_back(nums[m]);
}
return result;
}
private:
vector<int> inOrderTraversal(TreeNode *root) {
stack<TreeNode *> s;
vector<int> result;
while(root) {
s.push(root);
root=root->left;
}
while(!s.empty()) {
TreeNode* node = s.top();
result.push_back(node->val);
if (node->right) {
node = node->right;
while(node) {
s.push(node);
node = node->left;
}
} else {
node = s.top();
s.pop();
while(!s.empty() && s.top()->right == node) {
node = s.top();
s.pop();
}
}
}
return result;
}
};
解法2: 还是中序遍历,然后用binary search找到最后一个<=target的节点,然后背向双指针一左一右找。
/**
* 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
* @param k: the given k
* @return: k values in the BST that are closest to the target
* we will sort your return value in output
*/
vector<int> closestKValues(TreeNode *root, double target, int k) {
// inorder traversal
#if 0
stack<TreeNode *> stk;
while (root || !stk.empty()) {
while (root) {
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
vecs.push_back(root->val);
root->right;
}
#endif
inorderTraversal(root);
// binary search to find the last entry <= target
int start = 0, end = vecs.size() - 1, findPos = -1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (vecs[mid] < target) {
start = mid;
} else if (vecs[mid] > target) {
end = mid;
} else {
findPos = mid;
break;
}
}
if (findPos == -1) {
if (abs(vecs[start] - target) <= abs(vecs[end] - target)) {
findPos = start;
start--;
}
else {
findPos = end;
end++;
}
}
// linear search to find k numbers starting from findPos
vector<int> res;
res.push_back(vecs[findPos]);
k--;
while (k && start >= 0 && end < vecs.size()) {
if (abs(vecs[start] - target) <= abs(vecs[end] - target)) res.push_back(vecs[start--]);
else res.push_back(vecs[end++]);
k--;
}
//下面两个while循环理论上只有一个运行
while (k > 0 && start > 0) {
res.push_back(vecs[start--]);
k--;
}
while (k > 0 && end < vecs.size()) {
res.push_back(vecs[end++]);
k--;
}
return res;
}
private:
vector<int> vecs;
void inorderTraversal(TreeNode *root) {
if (root) {
inorderTraversal(root->left);
vecs.push_back(root->val);
inorderTraversal(root->right);
}
return;
}
};