/**
* 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) {
Deque<Integer> deque = new LinkedList<>();
TreeNode floor = getFloor(root, (int)target);
TreeNode ceiling = getCeiling(root,(int) target + 1);
while(deque.size() < k && !(floor == null && ceiling == null)){
if(floor == null || ceiling != null && Math.abs(floor.val - target) > Math.abs(ceiling.val - target)){
deque.offerLast(ceiling.val);
ceiling = getCeiling(root,ceiling.val+1);
}else{
deque.offerFirst(floor.val);
floor = getFloor(root, floor.val-1);
}
}
return new ArrayList<>(deque);
}
public TreeNode getFloor(TreeNode node, int target){
if(node == null) {
return null;
}
if(target == node.val) {
return node;
} else if(target < node.val) {
return getFloor(node.left, target);
} else {
TreeNode n = getFloor(node.right, target);
return n == null ? node : n;
}
}
public TreeNode getCeiling(TreeNode node, int target){
if(node == null) {
return null;
}
if(target == node.val) {
return node;
} else if(target > node.val) {
return getCeiling(node.right, target);
} else {
TreeNode n = getCeiling(node.left, target);
return n == null ? node : n;
}
}
}
时间复杂度 o(k+logn)
/**
* 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<>();
if(root == null)
return res;
Stack<TreeNode> larger = new Stack<>();
Stack<TreeNode> smaller = new Stack<>();
TreeNode cur = root;
while(cur != null){
if(cur.val < target){
smaller.push(cur);
cur = cur.right;
}else{
larger.push(cur);
cur = cur.left;
}
}
while(res.size() < k ){
double diffs = smaller.isEmpty()? Long.MAX_VALUE : Math.abs(smaller.peek().val - target);
double diffl = larger.isEmpty() ? Long.MAX_VALUE : Math.abs(larger.peek().val-target);
if(diffs < diffl){
res.add(smaller.peek().val);
getPrev(smaller);
}else{
res.add(larger.peek().val);
getNext(larger);
}
}
return res;
}
public void getPrev(Stack<TreeNode> stack){
TreeNode node = stack.pop();
TreeNode cur = node.left;
while(cur != null){
stack.push(cur);
cur = cur.right;
}
}
public void getNext(Stack<TreeNode> stack){
TreeNode node = stack.pop();
TreeNode cur = node.right;
while(cur != null){
stack.push(cur);
cur = cur.left;
}
}
}
优化 时间复杂度 o(k+logn),空间复杂度 o(logN)
use two stack to save the treenode, one stack is for treenode val smaller than target, other one is for treenode val larger or equal with target, . then if the res.size < k, just get peek of the two stack, to compare the distance, after select one, update the stack. for example, I picked the stack from the smaller value stack, then I go to the stack.pop node's right, which is larger than the picked node. Then go to the node's left, this is trying to find the fist node larger than the peek(). same with larger stack.