1. 程式人生 > >LeetCode096——不同的二叉搜尋樹

LeetCode096——不同的二叉搜尋樹

題目描述:

知識點:動態規劃

本題可以理解為是LeetCode095——不同的二叉搜尋樹 II的子問題,因為本題只需要求以1 ... n為節點組成的二叉搜尋樹有多少種,並不需要求二叉搜尋樹具體是怎麼樣的。因此,我們完全可以用LeetCode095——不同的二叉搜尋樹 II的思路來解決本題。

時間複雜度和空間複雜度均是O(n ^ n)。

JAVA程式碼:

public class Solution {

    public int numTrees(int n) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            arrayList.add(i);
        }
        return numTrees(arrayList);
    }

    private int numTrees(ArrayList<Integer> arrayList){
        if(arrayList.size() == 1){
            return 1;
        }
        int count = 0;
        for (int i = 0; i < arrayList.size(); i++) {
            int tempRoot = arrayList.get(i);
            ArrayList<Integer> less = new ArrayList<>();
            ArrayList<Integer> greater = new ArrayList<>();
            for (int j = 0; j < arrayList.size(); j++) {
                if(j == i){
                    continue;
                }
                if(arrayList.get(j) < arrayList.get(i)){
                    less.add(arrayList.get(j));
                }else{
                    greater.add(arrayList.get(j));
                }
            }
            if(less.size() == 0 && greater.size() != 0){
                count += numTrees(greater);
            }else if(less.size() != 0 && greater.size() == 0){
                count += numTrees(less);
            }else{
                count += numTrees(less) * numTrees(greater);
            }
        }
        return count;
    }
}

思路二:[1, 2, 3]和[4, 5, 6]能構成的二叉搜尋樹的數量相同(在LeetCode中提交會超時)

思路一用LeetCode095——不同的二叉搜尋樹 II的演算法我們多求了很多額外的資訊,我們並不需要知道每一棵二叉搜尋樹的確切組成是怎麼樣的。

對於陣列[1, 2, 3]和陣列[4, 5, 6]而言,雖然其能構成的二叉搜尋樹的具體組成是不一樣的,但是其能構成的二叉搜尋樹的數量卻是相同的。基於這一點,我們在遞迴的時候無需傳遞ArrayList型的集合型別來儲存具體的數字是哪幾個,我們只需傳遞數字的個數n即可。

時間複雜度和空間複雜度均是O(n ^ n)。

JAVA程式碼:

public class Solution {

    public int numTrees(int n) {
        if(n == 1){
            return 1;
        }
        int count = 0;
        for (int i = 1; i <= n; i++) {
            if(i == 1 || i == n){
                count += numTrees(n - 1);
            }else{
                count += numTrees(i - 1) * numTrees(n - i);
            }
        }
        return count;
    }
}

思路三:動態規劃

狀態定義

f(x) -------- 以 1 ... x 為節點組成的二叉搜尋樹的數量

狀態轉移

(1)當x == 1時,顯然f(x) = 1。

(2)當x > 1時,對於其左子樹,我們可以取其節點數量為0、1、2、... 、n - 1,相應的右子樹數量為n - 1、n - 2、... 、1、0。

對於每一對組合,都應該用乘法將其相乘,再將各個乘積相加即得f(x)的值。

時間複雜度和空間複雜度均是O(n)。

JAVA程式碼:

public class Solution {

    public int numTrees(int n) {
        int[] counts = new int[n + 1];
        counts[1] = 1;
        for (int i = 2; i <= n; i++) {
            counts[i] = counts[i - 1] * 2;
            for (int j = 1; j < i - 1; j++) {
                counts[i] += counts[j] * counts[i - j - 1];
            }
        }
        return counts[n];
    }
}

LeetCode解題報告: