1. 程式人生 > 實用技巧 >【LeetCode/LintCode】 題解丨美團面試題:二叉搜尋樹中最接近的值

【LeetCode/LintCode】 題解丨美團面試題:二叉搜尋樹中最接近的值

給一棵非空二叉搜尋樹以及一個target值,找到在BST中最接近給定值的節點值

  • 給出的目標值為浮點數
  • 我們可以保證只有唯一一個最接近給定值的節點

線上評測地址:LintCode 領釦

樣例1

輸入: root = {5,4,9,2,#,8,10} and target = 6.124780
輸出: 5
解釋:
二叉樹 {5,4,9,2,#,8,10},表示如下的樹結構:
        5
       / \
     4    9
    /    / \
   2    8  10

樣例2

輸入: root = {3,2,4,1} and target = 4.142857
輸出: 4
解釋:
二叉樹 {3,2,4,1},表示如下的樹結構:
     3
    / \
  2    4
 /
1

【題解】

演算法很簡單,求出 lowerBound 和 upperBound。即 < target 的最大值和 >= target 的最小值。 然後在兩者之中去比較誰更接近,然後返回即可。

時間複雜度為 O(h),注意如果你使用 in-order traversal 的話,時間複雜度會是 o(n) 並不是最優的。另外複雜度也不是 O(logn) 因為BST 並不保證樹高是 logn 的。

class Solution {
    public int closestValue(TreeNode root, double target) {
        if (root == null) {
            return 0;
        }
        
        TreeNode lowerNode = lowerBound(root, target);
        TreeNode upperNode = upperBound(root, target);
        
        if (lowerNode == null) {
            return upperNode.val;
        }
        
        if (upperNode == null) {
            return lowerNode.val;
        }
        
        if (target - lowerNode.val > upperNode.val - target) {
            return upperNode.val;
        }
        
        return lowerNode.val;
    }
    
    // find the node with the largest value that smaller than target
    private TreeNode lowerBound(TreeNode root, double target) {
        if (root == null) {
            return null;
        }
        
        if (target <= root.val) {
            return lowerBound(root.left, target);
        }
        
        // root.val < target
        TreeNode lowerNode = lowerBound(root.right, target);
        if (lowerNode != null) {
            return lowerNode;
        }
        
        return root;
    }
    
    // find the node with the smallest value that larger than or equal to target
    private TreeNode upperBound(TreeNode root, double target) {
        if (root == null) {
            return null;
        }
        
        if (root.val < target) {
            return upperBound(root.right, target);
        }
        
        // root.val >= target
        TreeNode upperNode = upperBound(root.left, target);
        if (upperNode != null) {
            return upperNode;
        }
        
        return root;
    }
}

更多題解參考:

九章演算法 - 幫助更多中國人找到好工作,矽谷頂尖IT企業工程師實時線上授課為你傳授面試技巧