https://www.cnblogs.com/grandyang/p/4301096.html
https://www.cnblogs.com/grandyang/p/4299608.html
卡塔兰数:https://zh.wikipedia.org/wiki/%E5%8D%A1%E5%A1%94%E5%85%B0%E6%95%B0
二叉搜索树:它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。
95. 递归
class Solution { public: vector<TreeNode*> generateTrees(int n) { if(!n) return {}; return helper(1,n); } vector<TreeNode*> helper(int start,int end) { if(start>end) return {nullptr}; vector<TreeNode*> vec; for(int i=start;i<=end;++i) { auto left=helper(start,i-1),right=helper(i+1,end); for(auto a:left) { for(auto b:right) { TreeNode* node=new TreeNode(i); node->left=a; node->right=b; vec.push_back(node); } } } return vec; } };
递归+记忆数组
class Solution { public: vector<TreeNode*> generateTrees(int n) { if(!n) return {}; vector<vector<vector<TreeNode*>>> memo(n,vector<vector<TreeNode*>>(n)); return helper(1,n,memo); } vector<TreeNode*> helper(int start,int end,vector<vector<vector<TreeNode*>>>& memo) { if(start>end) return {nullptr}; if(!memo[start-1][end-1].empty()) return memo[start-1][end-1]; vector<TreeNode*> vec; for(int i=start;i<=end;++i) { auto left=helper(start,i-1,memo),right=helper(i+1,end,memo); for(auto a:left) { for(auto b:right) { TreeNode* node=new TreeNode(i); node->left=a; node->right=b; vec.push_back(node); } } } memo[start-1][end-1]=vec; return vec; } };
96. dp[i]表示节点数为i时,总共有多少种二叉搜索树;dp[i]=dp[j]*dp[i-j-1]表示左子树有j个节点,右子树有i-j-1个节点,左子树的所有情况*右子树的情况表示排列。
class Solution { public: int numTrees(int n) { vector<int> dp(n+1); dp[0]=dp[1]=1; int i=0,j=0; for(i=2;i<=n;++i) { for(j=0;j<i;++j) { dp[i]+=dp[j]*dp[i-j-1]; } } return dp[n]; } };