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.
Follow up:
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?
Hint:
1. Consider implement these two helper functions:
i. getPredecessor(N), which returns the next smaller node to N.
ii. getSuccessor(N), which returns the next larger node to N.
2. Try to assume that each node has a parent pointer, it makes the problem much easier.
3. Without parent pointer we just need to keep track of the path from the root to the current node using a stack.
4. You would need two stacks to track the path in finding predecessor and successor node separately.
270. Closest Binary Search Tree Value 的拓展,270题只要找出离目标值最近的一个节点值,而这道题要找出离目标值最近的k个节点值。
解法1:Brute Force, 中序遍历或者其它遍历,同时维护一个大小为k的max heap。
Java:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List closestKValues(TreeNode root, double target, int k) {
LinkedList res = new LinkedList<>();
inOrderTraversal(root, target, k, res);
return res;
}
private void inOrderTraversal(TreeNode root, double target, int k, LinkedList res) {
if (root == null) {
return;
}
inOrderTraversal(root.left, target, k, res);
if (res.size() < k) {
res.add(root.val);
} else if(res.size() == k) {
if (Math.abs(res.getFirst() - target) > (Math.abs(root.val - target))) {
res.removeFirst();
res.addLast(root.val);
} else {
return;
}
}
inOrderTraversal(root.right, target, k, res);
}
}
Java:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private PriorityQueue minPQ;
private int count = 0;
public List closestKValues(TreeNode root, double target, int k) {
minPQ = new PriorityQueue(k);
List result = new ArrayList();
inorderTraverse(root, target, k);
// Dump the pq into result list
for (Integer elem : minPQ) {
result.add(elem);
}
return result;
}
private void inorderTraverse(TreeNode root, double target, int k) {
if (root == null) {
return;
}
inorderTraverse(root.left, target, k);
if (count < k) {
minPQ.offer(root.val);
} else {
if (Math.abs((double) root.val - target) < Math.abs((double) minPQ.peek() - target)) {
minPQ.poll();
minPQ.offer(root.val);
}
}
count++;
inorderTraverse(root.right, target, k);
}
}
Java:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List closestKValues(TreeNode root, double target, int k) {
PriorityQueue maxHeap = new PriorityQueue(k, new Comparator() {
@Override
public int compare(Double x, Double y) {
return (int)(y-x);
}
});
Set set = new HashSet();
rec(root, target, k, maxHeap, set);
return new ArrayList(set);
}
private void rec(TreeNode root, double target, int k, PriorityQueue maxHeap, Set set) {
if(root==null) return;
double diff = Math.abs(root.val-target);
if(maxHeap.size() target) rec(root.left, target, k, maxHeap,set);
else rec(root.right, target, k, maxHeap, set);
return;
}
rec(root.left, target, k, maxHeap, set);
rec(root.right, target, k, maxHeap, set);
}
}
Java: A time linear solution, The time complexity would be O(k + (n - k) logk). Space complexity is O(k).
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List closestKValues(TreeNode root, double target, int k) {
List result = new ArrayList<>();
if (root == null) {
return result;
}
Stack precedessor = new Stack<>();
Stack successor = new Stack<>();
getPredecessor(root, target, precedessor);
getSuccessor(root, target, successor);
for (int i = 0; i < k; i++) {
if (precedessor.isEmpty()) {
result.add(successor.pop());
} else if (successor.isEmpty()) {
result.add(precedessor.pop());
} else if (Math.abs((double) precedessor.peek() - target) < Math.abs((double) successor.peek() - target)) {
result.add(precedessor.pop());
} else {
result.add(successor.pop());
}
}
return result;
}
private void getPredecessor(TreeNode root, double target, Stack precedessor) {
if (root == null) {
return;
}
getPredecessor(root.left, target, precedessor);
if (root.val > target) {
return;
}
precedessor.push(root.val);
getPredecessor(root.right, target, precedessor);
}
private void getSuccessor(TreeNode root, double target, Stack successor) {
if (root == null) {
return;
}
getSuccessor(root.right, target, successor);
if (root.val <= target) {
return;
}
successor.push(root.val);
getSuccessor(root.left, target, successor);
}
}
C++:
class Solution {
public:
vector closestKValues(TreeNode* root, double target, int k) {
vector res;
priority_queue> q;
inorder(root, target, k, q);
while (!q.empty()) {
res.push_back(q.top().second);
q.pop();
}
return res;
}
void inorder(TreeNode *root, double target, int k, priority_queue> &q) {
if (!root) return;
inorder(root->left, target, k, q);
q.push({abs(root->val - target), root->val});
if (q.size() > k) q.pop();
inorder(root->right, target, k, q);
}
};
类似题目:
[LeetCode] 270. Closest Binary Search Tree Value 最近的二叉搜索树的值
All LeetCode Questions List 题目汇总