Problem:

Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.

Note:

  • 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.

Follow up:
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?

Analysis:

This problem is not hard. But the description of the problem is really quite misleading. It strongly hints you to use the characteristics of balance tree. I fail to achieve that. But there is also a very innovative and efficient way to solve this problem. 

Ask: Where are closest nodes of a give number ?
The predecessors and successors of a given number are the best candidates for you to choice, based on how many closest nodes you want.
And we already know through a inorder traversal we shoud easily get the tree in sorted form. It's really easy for us to find the closestKValues in the sorted form.
1 2 3 5 6 [target: 7] 8 10 23 25 But for this problem, we could solve it in more elegant way. Use the idea we have used in merging k sorted list.
Predecessors list: 6 5 3 2 1
Successors: 8 10 23 25 Basic knowledge enhancement
Through ordinary preorder traversal (scan left subtree first), we could get the binary search tree in the ascending order.
1 2 3 5 6 8 10 23 25
Through reverse preorder traversal (scan right subtree first), we could get the binary search tree in the descending order.
25 23 10 8 6 5 3 2 1 Step 1: get the predecessors list : 6 5 3 2 1 (descending order), through a stack.
------------------------------------------------------------------------
preOrderTraversal(is_reverse ? root.left, target, stack, is_reverse);
...
stack.push(root.val)
preOrderTraversal(is_reverse ? root.right, target, stack, is_reverse);
------------------------------------------------------------------------ Step 2: get the successors list : 8 10 23 25 (ascending order), through a stack.
------------------------------------------------------------------------
preOrderTraversal(is_reverse ? root.right, target, stack, is_reverse);
...
stack.push(root.val)
preOrderTraversal(is_reverse ? root.left, target, stack, is_reverse);
------------------------------------------------------------------------ A skill in getting "6 5 3 2 1" rather than "25 23 10 8 6 5 3 2 1".
if ((!is_reverse && root.val > target))
return;
//Great during the traversal process, we stop when we reach a node larger than target. A skill in getting "8 10 23 25" rahter than "25 23 10 8 6 5 3 2 1"
if (is_reverse && root.val <= target)
return;
Note: we use the same termination skill at here. Another skill to be careful (note when there is a stack was used up)
if (pre.isEmpty()) {
ret.add(suc.pop());
} else if (suc.isEmpty()) {
ret.add(pre.pop());
}
You must detect and handle above cases.

Solution:

public class Solution {
public List<Integer> closestKValues(TreeNode root, double target, int k) {
List<Integer> ret = new ArrayList<Integer> ();
Stack<Integer> pre = new Stack<Integer> ();
Stack<Integer> suc = new Stack<Integer> ();
preOrderTraversal(root, target, pre, false);
preOrderTraversal(root, target, suc, true);
int count = 0;
while (count < k) {
if (pre.isEmpty()) {
ret.add(suc.pop());
} else if (suc.isEmpty()) {
ret.add(pre.pop());
} else if (Math.abs(target - pre.peek()) < Math.abs(target - suc.peek())) {
ret.add(pre.pop());
} else {
ret.add(suc.pop());
}
count++;
}
return ret;
} private void preOrderTraversal(TreeNode root, double target, Stack<Integer> stack, boolean is_reverse) {
if (root == null)
return;
preOrderTraversal(is_reverse ? root.right : root.left, target, stack, is_reverse);
if ((is_reverse && root.val <= target) || (!is_reverse && root.val > target))
return;
stack.push(root.val);
preOrderTraversal(is_reverse ? root.left : root.right, target, stack, is_reverse);
}
}

[LeetCode#272] Closest Binary Search Tree Value II的更多相关文章

  1. [LeetCode] 272. Closest Binary Search Tree Value II 最近的二叉搜索树的值 II

    Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...

  2. [LeetCode] 272. Closest Binary Search Tree Value II 最近的二分搜索树的值之二

    Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...

  3. [leetcode]272. Closest Binary Search Tree Value II二叉搜索树中最近的值2

    Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...

  4. 272. Closest Binary Search Tree Value II

    题目: Given a non-empty binary search tree and a target value, find k values in the BST that are close ...

  5. LC 272. Closest Binary Search Tree Value II 【lock,hard】

    Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...

  6. [Locked] Closest Binary Search Tree Value & Closest Binary Search Tree Value II

    Closest Binary Search Tree Value  Given a non-empty binary search tree and a target value, find the ...

  7. [LeetCode] Closest Binary Search Tree Value II 最近的二分搜索树的值之二

    Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...

  8. LeetCode Closest Binary Search Tree Value II

    原题链接在这里:https://leetcode.com/problems/closest-binary-search-tree-value-ii/ 题目: Given a non-empty bin ...

  9. [Swift]LeetCode272. 最近的二分搜索树的值 II $ Closest Binary Search Tree Value II

    Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...

随机推荐

  1. Poj 1503 Integer Inquiry

    1.链接地址: http://poj.org/problem?id=1503 2.题目: Integer Inquiry Time Limit: 1000MS   Memory Limit: 1000 ...

  2. html5 css3 如何绘制扇形任意角度

    扇形制作原理,底部一个纯色原形,里面2个相同颜色的半圆,可以是白色,内部半圆按一定角度变化,就可以产生出扇形效果 <html> <head> <meta charset= ...

  3. php获取汉字首字母的函数

    本文介绍用php实现汉字转化为首字母的方法,主要功能是:功能明确,易于修改维护和扩展: 英文的字串:不变返回(包括数字):中文字符串:返回拼音首字符: 中英混合串: 返回拼音首字符和英文. 网上的方法 ...

  4. 修改VC++2010界面左上角图标

    (1)在Resource View中创建或者插入一个新的Icon资源,用于你想要的程序图标,假设ID号为IDI_ICON(这种图标要有16*16和32*32两种格式的,前者用于最小化和列表显示等,后者 ...

  5. 寻找序列中最小的第N个元素(partition函数实现)

    Partition为分割算法,用于将一个序列a[n]分为三部分:a[n]中大于某一元素x的部分,等于x的部分和小于x的部分. Partition程序如下: long Partition (long a ...

  6. CSS3 关于@font-face引用中文字体解决办法

    有两种方法,一种简单的,一种比较复杂,都可以实现(注:这里的方法只适合使用少量的中文字体,如果使用的字量过大,请使用其他方法解决) 第一种:简单的 1.下载需要的中文字体的.ttf格式,这个都不难找到 ...

  7. 安装ARM调试器

    一.概述 1.调试ARM应用程序的软硬件组成 硬件JTAG/SWD仿真器 Eclipse调试插件 GDB调试客户端 GDB服务器端 JTAG/SWD需要的硬件驱动 2.GNU ARM Eclipse推 ...

  8. SDC(3)–set_multicycle_path 最关键的一张图

    上图意思是,假如使用 –setup option,默认约束的是 latch clock:假如使用 –hold option,默认约束的是 launch clock.箭头表示不同组合下时钟沿的移动方向. ...

  9. Python创建list

    Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: >>> ['Mic ...

  10. Grails的redirect无法跳转时的一个可能原因

    由于controller的命名一般首字母大写,如Login 此时如 class LoginController { def index = { redirect(action:Login, param ...