Given the root of a binary search tree, a target value, and an integer k, return thekvalues in the BST that are closest to thetarget. You may return the answer in any order.
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)?
ac: iterative, 1 list + 1 stack
O(n) time key idea is in-order traversal of BST is incremental, make use of it.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> closestKValues(TreeNode root, double target, int k) {
List<Integer> res = new ArrayList<Integer>();
// edge cases
if (root == null || k <= 0) return res;
// get in-order list
List<Integer> inorder = new ArrayList<Integer>();
int closestIndex = 0;
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if (inorder.size() != 0 && Math.abs(target - root.val) < Math.abs(target - inorder.get(inorder.size() - 1))) closestIndex = inorder.size();
inorder.add(root.val);
root = root.right;
}
// compare left and right, add to result list
res.add(inorder.get(closestIndex));
int l = closestIndex - 1, r = closestIndex + 1;
while (res.size() < k) {
if (l < 0) {
res.add(inorder.get(r));
r++;
} else if (r >= inorder.size()) {
res.add(inorder.get(l));
l--;
} else if (Math.abs(target - inorder.get(l)) < Math.abs(target - inorder.get(r))) {
res.add(inorder.get(l));
l--;
} else {
res.add(inorder.get(r));
r++;
}
}
return res;
}
}
/*
get in-order list
find closest index
compare left and right, add to result list
*/
ac2: recursive
maintain a k size window
class Solution {
public List<Integer> closestKValues(TreeNode root, double target, int k) {
LinkedList<Integer> res = new LinkedList<Integer>();
// edge cases
if (root == null || k <= 0) return res;
traverse(root, target, k, res);
return res;
}
private void traverse(TreeNode root, double target, int k, LinkedList<Integer> res) {
// exit
if (root == null) return;
// root.left
traverse(root.left, target, k, res);
// root
if (res.size() == k) {
int h = res.getFirst();
if (Math.abs(target - h) > Math.abs(target - root.val)) {
res.removeFirst();
res.add(root.val);
} else {
return; // result found, terminate early
}
} else {
res.add(root.val);
}
// root.right
traverse(root.right, target, k, res);
}
}