每天一道LeetCode-----生成由[1 : n]这n个数组成的所有二叉搜索树
Unique Binary Search Trees
原題鏈接Unique Binary Search Trees
給定數值n,計算有多少種不同的二叉搜索樹能夠存儲1,2,...,n這n個數
二叉搜索樹滿足的條件
- 當前根節點的值大于左子樹節點的值
- 當前根節點的值小于右子樹節點的值
- 左右子樹同樣是二叉搜索樹
根據上述規則可以看出,根節點值不同,形成的二叉搜索樹就不同,那么[1:n]范圍內的n個數就有n個不同的選擇
假設選取i作為根節點值,根據二叉搜索樹的規則,[1:i?1]這i-1個數在其左子樹上,[i+1:n]這n-i個數在其右子樹上
對于由[1:i?1]形成的左子樹,又可以采用上述方法進行分解
對于由[i+1:n]形成的右子樹,同樣可以采用上述方法進行分解
由于每個分解的范圍都是連續遞增的,所以無需考慮具體數值。另G(n)表示由連續的n個數形成的二叉搜索樹的個數
那么G(n)為所求解,假設以i作為分界點,那么左子樹為G(i-1),右子樹為G(n-i)
因為i可以取從1到n的任意一個數,所以G(n)=∑ni=1(G(i?1)?G(n?i))
需要對G(0)和G(1)特殊處理,令其為1,即G(0)=G(1)=1
代碼如下
class Solution { public:int numTrees(int n) {vector<int> dp(n + 1, 0);dp[0] = dp[1] = 1;for(int i = 2; i <= n; ++i){for(int j = 1; j <= i; ++j){//G(i) += G(j - 1) * G(n - j)dp[i] += dp[j - 1] * dp[i - j];}}return dp[n];} };Unique Binary Search Trees II
原題鏈接Unique Binary Search Trees II
不再是計算有多少個不同的二叉搜索樹,而是將所有不同的二叉搜索樹構造出來:smile:
還是以上面的題為基礎,假設選擇i作為分界點,那么左子樹由[1:i?1]范圍的值組成,右子樹由[i+1:n]范圍內的值組成
通過[1:i?1]這i-1個數可以構成多個不同的二叉搜索樹,假設是leftTree1,leftTree2,....,leftTreeL
通過[i+1:n]這n-i個數可以構成多個不同的二叉搜索樹,假設是rightTree1,rightTree2,...,rightTreeR
那么可知以i作為根節點的二叉搜索樹共有L?R個,另這些樹依次組成即可求出這L?R個樹
代碼如下
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:vector<TreeNode*> generateTrees(int n) {return generateTrees(1, n); } private://返回由[start : end]組成的所有樹vector<TreeNode*> generateTrees(int start, int end){vector<TreeNode*> trees;//如果只有一個元素,直接構建返回if(start == end){trees.emplace_back(new TreeNode(start));return trees;}//范圍內無元素,直接返回if(start > end){return trees;}for(int i = start; i <= end; ++i){//以i作為分界點獲取左右兩部分的子樹集合vector<TreeNode*> leftTrees = generateTrees(start, i - 1);vector<TreeNode*> rightTrees = generateTrees(i + 1, end);//如果是空,手動增加nullptr節點,否則for循環進不去!!!if(leftTrees.empty()) leftTrees.emplace_back(nullptr);if(rightTrees.empty()) rightTrees.emplace_back(nullptr);//依次組合所有可能for(auto leftTree : leftTrees){for(auto rightTree : rightTrees){//構建以i為值的根節點,添加左右子樹,添加到結果中TreeNode *root = new TreeNode(i);root->left = leftTree;root->right = rightTree;trees.emplace_back(root);}}}//繼續返回上一層return trees;} };這兩道題比較重要,真的很重要:cry:
對于如何構建二叉搜索樹,只需要將其拆分成左右兩部分,再組合集合。計算所有BST的數量利用的是動態規劃,公式推導一遍應該可以理解(Letex公式真的好用:smile:)
總結
以上是生活随笔為你收集整理的每天一道LeetCode-----生成由[1 : n]这n个数组成的所有二叉搜索树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每天一道LeetCode-----寻找二
- 下一篇: 每天一道LeetCode-----对表达