zoukankan      html  css  js  c++  java
  • [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;
        }
    }
  • 相关阅读:
    NYOJ题目916胖子小的百宝袋
    NYOJ题目893十字架
    NYOJ题目874签到
    设计模式之Singleton
    Elo rating system 模拟
    JDBC之SqlHelper
    《Thinking in Java》十四章类型信息_习题解
    NYOJ题目842整除的尾数
    NYOJ题目840吃花生
    NYOJ题目839合并
  • 原文地址:https://www.cnblogs.com/airwindow/p/4799802.html
Copyright © 2011-2022 走看看