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

leetcode96_不同的二叉搜尋樹

給定一個整數 n,求以 1 ... n 為節點組成的二叉搜尋樹有多少種?

示例:

輸入: 3
輸出: 5
解釋:
給定 n = 3, 一共有 5 種不同結構的二叉搜尋樹:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

 

思路;

/*
     * 既然是二叉搜尋樹 那麼中序的結果為1 2 3 . . . n
     * 根據二叉搜尋樹可以知道,某根節點x,它的左子樹的值全<=x(當然本題不存在等於的情況),它的右子樹的值全>=x, 所以,當它的根節點是 1
     * 的時候,左子樹個數為 0 ,右子樹的個數為 n-1, 當它的根節點為 2 的時候, 左子樹個數為 1, 右子樹的個數為 n-2…… x-1個 x n-x個
     * 還有一個規律,就是這棵樹的不同形態的二叉查詢樹的個數,就是根節點的 左子樹的個數*右子樹的個數,想想還是很
     * 容易理解的,就是左邊的所有情況乘以右邊的所有情況 動態規劃,dp[i]從前到後計算出當有i個節點時,它有多少種不同形態的樹
     */

    /*
     * 就跟斐波那契數列一樣,我們把n = 0 時賦為1,因為空樹也算一種二叉搜尋樹,那麼n = 1時的情況可以看做是其左子樹個數乘以右子樹的個數,
     * 左右字數都是空樹,所以1乘1還是1。那麼n = 2時,由於1和2都可以為跟,分別算出來,再把它們加起來即可
     */

 

public static int numTrees(int n) {
		if (n == 0)
			return 0;
		if (n == 1)
			return 1;
		int[] dp = new int[n + 1];
		dp[0] = 1;
		dp[1] = 1;
		// 當節點個數為0時有一種形態的樹(也就是空樹吧),當節點個數為1時有一種形態的樹,之後就可以向下繼續計算節點為2,3,4,5,……n
		for (int i = 2; i <= n; i++) { //控制有多少個節點
			for (int j = 0; j < i; j++) {
				//  dp[j] * dp[i-1-j]為新加的j作為根節點 得到的情況數
				dp[i] = dp[i] + dp[j] * dp[i - 1 - j];
			}
		}
		return dp[n];
	}