1. 程式人生 > >LeetCode783題:二叉搜尋樹結點最小距離

LeetCode783題:二叉搜尋樹結點最小距離

思路一:中序遍歷然後迴圈比較

這道題其實跟第530題是一樣的。都是求二叉搜尋樹的任意兩個結點之差的最小值。這時候關鍵要清楚二叉搜尋樹的原理,即當前節點大於其左子樹小於其右子樹。同時考慮到二叉搜尋樹的中序遍歷實際上一個正序排序的過程,因此可以先對二叉搜尋樹中序遍歷並儲存到list中,然後迴圈比較前後兩個元素之差找到最小差即可。

public int minDiffInBST(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        help(root,list);
        Object[] arr = list.toArray();
        int res = Integer.MAX_VALUE;
        for(int i=1;i<arr.length;i++){
            res = ((Integer)arr[i] - (Integer)arr[i-1])<res?((Integer)arr[i] - (Integer)arr[i-1]):res;
        }
        return res;
    }
    public void help(TreeNode root,ArrayList<Integer> list){
        if(root == null){
            return;
        }
        help(root.left,list);
        list.add(root.val);
        help(root.right,list);
    }

思路二:一次遍歷每個結點

這道題其實跟第530題是一樣的。都是求二叉搜尋樹的任意兩個結點之差的最小值。這時候關鍵要清楚二叉搜尋樹的原理,即當前節點大於其左子樹小於其右子樹。因此,如果某一個結點(假設為temp)與另一個結點(假設為next)的差值最小,那麼next要麼是temp的左子樹的最大值,要麼是temp的右子樹的最小值,也就是要麼在temp的左子樹的最右邊,要麼在temp的右子樹的最左邊。這樣就可以遍歷每一個結點,並求出其最小差。

public int minDiffInBST(TreeNode root) {
        if(root == null || (root.left == null && root.right == null))
            return Integer.MAX_VALUE;
        int temp = root.val;
        int leftMax = temp;
        int rightMin = temp;
        //左子樹
        TreeNode leftTree = root.left;
        //右子樹
        TreeNode rightTree = root.right;
        //尋找左子樹的最大值
        while(leftTree != null){
            leftMax = leftTree.val;
            leftTree = leftTree.right;
        }
        //尋找右子樹的最小值
        while(rightTree != null){
            rightMin = rightTree.val;
            rightTree = rightTree.left;
        }
        
        if(root.left == null){
            int res = rightMin - temp;
            return Math.min(res,minDiffInBST(root.right));
        }
        if(root.right == null){
            int res = temp - leftMax;
            return Math.min(res,minDiffInBST(root.left));
        }
        int res = (temp - leftMax) < (rightMin - temp)?(temp - leftMax):(rightMin - temp);
        int left = minDiffInBST(root.left);
        int right = minDiffInBST(root.right);
        return Math.min(res,Math.min(left,right));
    }

總結:

第二種方法要比第一種效率高,但第一種寫起來簡單。