LeetCode096——不同的二叉搜尋樹
阿新 • • 發佈:2018-12-16
題目描述:
知識點:動態規劃
本題可以理解為是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解題報告: