lintcode901

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;
        
    }
}
原文地址:https://www.cnblogs.com/jasminemzy/p/9576617.html