Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.
Example
Given root = {1}, target = 0.000000, k = 1, return [1].
Challenge
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?
Notice
* 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.
O(n) 时间复杂度
一次中序遍历得到排序链表,顺便记录一下最接近的数,接着用双指针从最接近的数向两边搜索,加入结果链表。
细节:
List有list.subList(from, to)方法。里面填的参数和substring一样,头包括,尾部包括,两者相减是长度。还有注意subList有驼峰,substring没驼峰。还有就是subList返回的实际上是一个view,原数组和子数组发生改变会影响对方,一般情况下不是特别安全,还是小心用。
/** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, right; * public TreeNode(int val) { * this.val = val; * this.left = this.right = null; * } * } */ public class Solution { /** * @param root: the given BST * @param target: the given target * @param k: the given k * @return: k values in the BST that are closest to the target */ public List<Integer> closestKValues(TreeNode root, double target, int k) { // write your code here Stack<TreeNode> stack = new Stack<>(); TreeNode crt = root; List<Integer> inOrder = new ArrayList<>(); int ceilingIndex = 0; boolean ceilingAppeared = false; while (crt != null || !stack.isEmpty()) { while (crt != null) { stack.push(crt); crt = crt.left; } crt = stack.pop(); inOrder.add(crt.val); if (!ceilingAppeared && crt.val >= target) { ceilingIndex = inOrder.size() - 1; ceilingAppeared = true; } crt = crt.right; } if (!ceilingAppeared) { // 注意这个方法。 return inOrder.subList(inOrder.size() - k, inOrder.size()); } int left = ceilingIndex, right = ceilingIndex + 1; List<Integer> result = new ArrayList<>(); while (result.size() < k) { if (left < 0) { result.add(inOrder.get(right++)); } else if (right >= inOrder.size()) { result.add(inOrder.get(left--)); } else if (Math.abs(target - inOrder.get(left)) < Math.abs(target - inOrder.get(right))){ result.add(inOrder.get(left--)); } else { result.add(inOrder.get(right++)); } } return result; } }