1. 程式人生 > >【兩次過】Lintcode 1188. BST的最小絕對差

【兩次過】Lintcode 1188. BST的最小絕對差

給定具有非負值的二叉搜尋樹,找到任意兩個節點的值之間的最小絕對差值.

樣例

輸入
   1
    \
     3
    /
   2

輸出:
1

說明:
最小絕對差值為1,即2和1(或2和3之間)之差。

注意事項

此BST中至少有兩個節點。


解題思路1:

我們知道按中序遍歷BST得到的節點值是遞增的,題目限定BST中所有節點值非負,因此只需要比較中序遍歷時所有相鄰節點的絕對差即可得到最小絕對差。這樣題目就變成了中序遍歷二叉樹的問題。

利用二叉搜尋樹的性質可知,所求值可能出現在以下兩處:

  • 根節點左/右子樹相鄰兩個節點之差
  • 根節點左子樹最大值和根節點右子樹最小值
    那麼利用遞迴,在遍歷時記錄上一個遍歷的節點(pre),然後用當前節點減去pre即可獲得相鄰節點之差。而且遍歷完左子樹最後一個節點,進入根節點右子樹前,pre剛好為左子樹最大值,而此時根節點為右子樹最小值,因此可以檢測條件2
/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    int min = Integer.MAX_VALUE;
    int pre = -1;
    /**
     * @param root: the root
     * @return: the minimum absolute difference between values of any two nodes
     */
    public int getMinimumDifference(TreeNode root) {
        // Write your code here
        if (root == null)
            return min;
        
        getMinimumDifference(root.left);
        
        if (pre != -1) 
            min = Math.min(min, root.val - pre);
        
        pre = root.val;
        
        getMinimumDifference(root.right);
        
        return min;
    }
    
    

}

解題思路2:

非遞迴。

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: the root
     * @return: the minimum absolute difference between values of any two nodes
     */
    public int getMinimumDifference(TreeNode root) {
        // Write your code here
        Stack<TreeNode> stack = new Stack<>();
        int pre = -1;
        int min = Integer.MAX_VALUE;
        
        while(root!=null || !stack.isEmpty()){
            while(root != null){
                stack.push(root);
                root = root.left;
            }
            
            root = stack.pop();
            if(pre != -1)
                min = Math.min(min, root.val - pre);
            
            pre = root.val;
            root = root.right;
        }
        
        return min;
    }
}