272. Closest Binary Search Tree Value II
Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.
Note:
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:
Input: root = [4,2,5,1,3], target = 3.714286, and k = 2
4
/ \
2 5
/ \
1 3
Output: [4,3]
Follow up:
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?
方法0: kth closest in vector
思路:
inorder遍历一遍得到有序数组,用658. Find K Closest Elements的方法找到所求结果。
Complexity
Time complexity: O(n)
Space complexity: O(n)
方法1:
grandyang:
思路:
在中序遍历的过程中完成查找,并且提前终止:当数组不满k个值的时候,不断放入;当满k个值,比较新来的数字和result左端点和x的相对距离。如果新的元素比左端点更接近,取代左端点,如果更远,那么由于BST的有序性,右边的所有数字会越来越远,可以终止。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> closestKValues(TreeNode* root, double target, int k) {
vector<int> result;
stack<TreeNode*> st;
while (true) {
while (root) {
st.push(root);
root = root -> left;
}
if (st.empty()) break;
auto top = st.top();
st.pop();
if (result.size() < k) {
result.push_back(top -> val);
}
else {
if (abs(result.front() - target) > abs(top -> val - target)) {
result.erase(result.begin());
result.push_back(top -> val);
}
else break;
}
root = top -> right;
}
return result;
}
};
方法2: two stacks
思路:
参考173. Binary Search Tree Iterator和285. Inorder Successor in BST。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> closestKValues(TreeNode* root, double target, int k) {
vector<int> result;
stack<TreeNode*> pre, suc;
while (root) {
if (root -> val <= target) {
pre.push(root);
root = root -> right;
}
else {
suc.push(root);
root = root -> left;
}
}
while (k--) {
if (suc.empty() || !pre.empty() && target - suc.top() -> val < pre.top() -> val - target) {
result.push_back(pre.top() -> val);
getPredecessor(pre);
}
else {
result.push_back(suc.top() -> val);
getSuccessor(suc);
}
}
return result;
}
void getPredecessor(stack<TreeNode*> & pre) {
TreeNode* top = pre.top();
pre.pop();
if (top -> left) {
pre.push(top -> left);
while (pre.top() -> right) pre.push(pre.top() -> right);
}
}
void getSuccessor(stack<TreeNode*> & suc) {
TreeNode* top = suc.top();
suc.pop();
if (top -> right) {
suc.push(top -> right);
while (suc.top() -> left) suc.push(suc.top() -> left);
}
}
};