Copy **Input:** root = [4,2,5,1,3], target = 3.714286, k = 2
**Output:** [4,3]
Copy **Input:** root = [1], target = 0.000000, k = 1
**Output:** [1]
ac: iterative, 1 list + 1 stack
O(n) time key idea is in-order traversal of BST is incremental, make use of it.
Copy /**
* 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
*/
Copy 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) ;
}
}