[LeetCode] Minimum Absolute Difference in BST 二叉搜索樹的最小絕對差


 

Given a binary search tree with non-negative values, find the minimum absolute difference between values of any two nodes.

Example:

Input:

   1
    \
     3
    /
   2

Output:
1

Explanation:
The minimum absolute difference is 1, which is the difference between 2 and 1 (or between 2 and 3).

 

Note: There are at least two nodes in this BST.

 

這道題給了我們一棵二叉搜索樹,讓我們求任意個節點值之間的最小絕對差。由於BST的左<根<右的性質可知,如果按照中序遍歷會得到一個有序數組,那么最小絕對差肯定在相鄰的兩個節點值之間產生。所以我們的做法就是對BST進行中序遍歷,然后當前節點值和之前節點值求絕對差並更新結果res。這里需要注意的就是在處理第一個節點值時,由於其沒有前節點,所以不能求絕對差。這里我們用變量pre來表示前節點值,這里由於題目中說明了所以節點值不為負數,所以我們給pre初始化-1,這樣我們就知道pre是否存在。如果沒有題目中的這個非負條件,那么就不能用int變量來,必須要用指針,通過來判斷是否為指向空來判斷前結點是否存在。還好這里簡化了問題,用-1就能搞定了,這里我們先來看中序遍歷的遞歸寫法,參見代碼如下:

 

解法一:

class Solution {
public:
    int getMinimumDifference(TreeNode* root) {
        int res = INT_MAX, pre = -1;
        inorder(root, pre, res);
        return res;
    }
    void inorder(TreeNode* root, int& pre, int& res) {
        if (!root) return;
        inorder(root->left, pre, res);
        if (pre != -1) res = min(res, root->val - pre);
        pre = root->val;
        inorder(root->right, pre, res);
    }
};

 

其實我們也不必非要用中序遍歷不可,用先序遍歷同樣可以利用到BST的性質,我們帶兩個變量low和high來分別表示上下界,初始化為int的極值,然后我們在遞歸函數中,分別用上下界和當前節點值的絕對差來更新結果res,參見代碼如下:

 

解法二:

class Solution {
public:
    int getMinimumDifference(TreeNode* root) {
        int res = INT_MAX;
        helper(root, INT_MIN, INT_MAX, res);
        return res;
    }
    void helper(TreeNode* root, int low, int high, int& res) {
        if (!root) return;
        if (low != INT_MIN) res = min(res, root->val - low);
        if (high != INT_MAX) res = min(res, high - root->val);
        helper(root->left, low, root->val, res);
        helper(root->right, root->val, high, res);
    }
};

 

下面這種方法是解法一的迭代的寫法,思路跟之前的解法沒有什么區別,參見代碼如下:

 

解法三:

class Solution {
public:
    int getMinimumDifference(TreeNode* root) {
        int res = INT_MAX, pre = -1;
        stack<TreeNode*> st;
        TreeNode *p = root;
        while (p || !st.empty()) {
            while (p) {
                st.push(p);
                p = p->left;
            }
            p = st.top(); st.pop();
            if (pre != -1) res = min(res, p->val - pre);
            pre = p->val;
            p = p->right;
        }
        return res;
    }
};

 

參考資料:

https://discuss.leetcode.com/topic/80896/my-solution-using-no-recursive-in-order-binary-tree-iteration

https://discuss.leetcode.com/topic/80823/two-solutions-in-order-traversal-and-a-more-general-way-using-treeset/2

https://discuss.leetcode.com/topic/80916/java-no-in-order-traverse-solution-just-pass-upper-bound-and-lower-bound

 

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


免責聲明!

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



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