[LeetCode] 270. Closest Binary Search Tree Value 最近的二分搜索樹的值


 

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.

Example:

Input: root = [4,2,5,1,3], target = 3.714286

    4
   / \
  2   5
 / \
1   3

Output: 4

 

這道題讓我們找一個二分搜索數的跟給定值最接近的一個節點值,由於是二分搜索樹,所以博主最先想到用中序遍歷來做,一個一個的比較,維護一個最小值,不停的更新,實際上這種方法並沒有提高效率,用其他的遍歷方法也可以,參見代碼如下:

 

解法一:

class Solution {
public:
    int closestValue(TreeNode* root, double target) {
        double d = numeric_limits<double>::max();
        int res = 0;
        stack<TreeNode*> s;
        TreeNode *p = root;
        while (p || !s.empty()) {
            while (p) {
                s.push(p);
                p = p->left;
            }
            p = s.top(); s.pop();
            if (d >= abs(target - p->val)) {
                d = abs(target - p->val);
                res = p->val;
            }
            p = p->right;
        }
        return res;
    }
};

 

實際我們可以利用二分搜索樹的特點 (左<根<右) 來快速定位,由於根節點是中間值,在往下遍歷時,根據目標值和根節點的值大小關系來比較,如果目標值小於節點值,則應該找更小的值,於是到左子樹去找,反之去右子樹找,參見代碼如下:

 

解法二:

class Solution {
public:
    int closestValue(TreeNode* root, double target) {
        int res = root->val;
        while (root) {
            if (abs(res - target) >= abs(root->val - target)) {
                res = root->val;
            }
            root = target < root->val ? root->left : root->right;
        }
        return res;
    }
};

 

以上兩種方法都是迭代的方法,下面來看遞歸的寫法,下面這種遞歸的寫法和上面迭代的方法思路相同,都是根據二分搜索樹的性質來優化查找,但是遞歸的寫法用的是回溯法,先遍歷到葉節點,然后一層一層的往回走,把最小值一層一層的運回來,參見代碼如下:

 

解法三:

class Solution {
public:
    int closestValue(TreeNode* root, double target) {
        int a = root->val;
        TreeNode *t = target < a ? root->left : root->right;
        if (!t) return a;
        int b = closestValue(t, target);
        return abs(a - target) < abs(b - target) ? a : b;
    }
};

 

再來看另一種遞歸的寫法,思路和上面的都相同,寫法上略有不同,用if來分情況,參見代碼如下:

 

解法三:

class Solution {
public:
    int closestValue(TreeNode* root, double target) {
        int res = root->val;
        if (target < root->val && root->left) {
            int l = closestValue(root->left, target);
            if (abs(res - target) >= abs(l - target)) res = l;
        } else if (target > root->val && root->right) {
            int r = closestValue(root->right, target);
            if (abs(res - target) >= abs(r - target)) res = r;
        }
        return res;
    }
};

 

最后來看一種分治法的寫法,這種方法相當於解法一的遞歸寫法,並沒有利用到二分搜索樹的性質來優化搜索,參見代碼如下:

 

解法四:

class Solution {
public:
    int closestValue(TreeNode* root, double target) {
        double diff = numeric_limits<double>::max();
        int res = 0;
        helper(root, target, diff, res);
        return res;
    }
    void helper(TreeNode *root, double target, double &diff, int &res) {
        if (!root) return;
        if (diff >= abs(root->val - target)) {
            diff = abs(root->val - target);
            res = root->val;
        }
        helper(root->left, target, diff, res);
        helper(root->right, target, diff, res);
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/270

 

類似題目:

Count Complete Tree Nodes

Closest Binary Search Tree Value II

Search in a Binary Search Tree

 

參考資料:

https://leetcode.com/problems/closest-binary-search-tree-value/

https://leetcode.com/problems/closest-binary-search-tree-value/discuss/70331/Clean-and-concise-java-solution

https://leetcode.com/problems/closest-binary-search-tree-value/discuss/70322/Super-clean-recursive-Java-solution

https://leetcode.com/problems/closest-binary-search-tree-value/discuss/70327/4-7-lines-recursiveiterative-RubyC%2B%2BJavaPython

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM