[LeetCode#270] Closest Binary Search Tree Value

Problem:

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

Note:

  • Given target value is a floating point.
  • You are guaranteed to have only one unique value in the BST that is closest to the target.

Wrong solution 1:

public class Solution {
    public int closestValue(TreeNode root, double target) {
        if (root == null)
            throw new IllegalArgumentException("root is null");
        int closest_gap = Integer.MAX_VALUE;
        int ret;
        while (root != null) {
            if (Math.abs(target - root.val) < closest_gap) {
                closest_gap = Math.abs(target - root.val);
                ret = root.val;
            }
            if (target == root.val)
                return root.val;
            else if (target < root.val)
                root = root.left;
            else
                root = root.right;
        }
        return ret;
    }
}

Mistakes Analysis:

Line 18: error: incompatible types: possible lossy conversion from double to int
Line 55: error: variable ret might not have been initialized

Mistake 1:
Even the problem has emphasized that target is a floating type, the val in node is Integer type. I still blindly ignore the fact that : the type used for recording the distance should be a float type rather than Integer. Otherwise, we could lose precision. 
Case :
target = 0.3
val_1: -1, val_2: 1
(int)(target - val_1) = 1;
(int)(target - val_2) = 1;

Wrong Fix:
double closest_gap = Integer.MAX_VALUE;
...
if (Math.abs(target - (double)root.val) < closest_gap) {
    closest_gap = Math.abs(target - (double)root.val);
    ret = root.val;
}
...

Mistake 2:
Since "ret" is a return value, and it was solely enclosed in if-else blocks, we must initialize it.

Wrong solution 2:

public class Solution {
    public int closestValue(TreeNode root, double target) {
        if (root == null)
            throw new IllegalArgumentException("root is null");
        double closest_gap = Integer.MAX_VALUE;
        int ret = 0;
        while (root != null) {
            if (Math.abs(target - (double)root.val) <= closest_gap) {
                closest_gap = Math.abs(target - (double)root.val);
                ret = root.val;
            }
            if (target == root.val)
                return root.val;
            else if (target < root.val)
                root = root.left;
            else
                root = root.right;
        }
        return ret;
    }
}

Mistakes Analysis:

Error Cases:
[1500000000,1400000000], -1500000000.0
Output:
0
Expected:
1400000000

Mistake Analysis:
Even though I have changed the type of "closet_gap" into double, I still fail to consider the single floating point "target" could have larger range than Integer, which would produce the distance larger than "Integer.MAX_VALUE".
double closest_gap = Integer.MAX_VALUE;

Fix:
double closest_gap = Double.MAX_VALUE;

Skill:

Finally, we get it right!!! But this a good lesson for us to learn a important skill: avoiding overflow through more advanced primitive types. Actually, we have meet it many times : reverse Integer, convert String into Integer.

We know:
Whether "add" or "minus", we could easily exceed the operand's value range.
Take Integer as example:
Integer.MAX_VALUE + 1  overflow;
Integer.MIN_VALUE - 1  overflow;

Even the operation between Integer with Double could easily result in overflow problem.
Double.MAX_VALUE + 1 overflow;
Double.MIN_VALUE - 1 overflow. 

Thus we have to take advantage of advanced type!!!
For the operations among Integer, we use long to hold the result. 
long res = integer1 + integer 2.

For this problem, we were guaranteed that the target is a single floating point, it means we can use "double" to handle the result. <or for the maximum comparision>
Note: closestValue(TreeNode root, double target) is a little misleading, but it is indeed a single floating point.

Solution:

public class Solution {
    public int closestValue(TreeNode root, double target) {
        if (root == null)
            throw new IllegalArgumentException("root is null");
        double closest_gap = Double.MAX_VALUE;
        int ret = 0;
        while (root != null) {
            if (Math.abs(target - (double)root.val) <= closest_gap) {
                closest_gap = Math.abs(target - (double)root.val);
                ret = root.val;
            }
            if (target == root.val)
                return root.val;
            else if (target < root.val)
                root = root.left;
            else
                root = root.right;
        }
        return ret;
    }
}

 

posted @ 2015-09-11 02:04  airforce  阅读(287)  评论(0编辑  收藏  举报