2020.7.15 力扣每日
1 class Solution { 2 public int numTrees(int n) { 3 int[] total = new int[n + 1]; 4 total[0] = 1; 5 total[1] = 1; 6 for (int i = 2; i <= n; ++i) { 7 for (int y = 1; y <= i; ++y) { 8 total[i] += total[y - 1] * total[i - y]; 9 } 10 } 11 return total[n]; 12 } 13 }
解题思路:
本题使用动态规划的方法,题目要求求出n个节点的二叉搜索树。由于所有的节点为1~n的序列,且根据二叉搜索树的特征,当选取了1~n中某个数,y作为根节点时,左子树为1~y-1,右子树则为y+1~n,且由于右子树的排列情况与1~n-y的排列情况一致。
所以此处分别使用total[y-1],total[n-y]来表示其排列情况,也就是说当y作为根节点时,不同的二叉搜索树总个数为total[y-1]*total[n-y]。再利用y遍历n,便可求出toatl[n]的状态方程为,total[n]+=total[y-1]*total[n-y],y∈[1,n]。但此时仍未知total的具体值,显然边界情况toatl[0],total[1]的值均为1,但total[2~n]的数值未知。此时便再利用一个i遍历n,将状态方程中的n改为i,便可求出最终结果。
注意点:
由于total需存储0~n的情况,所以total数组的容量为n+1,遍历时i范围为[2,n],y范围为[1,i]
空间复杂度: O(n)
时间复杂度: O(n^2)
题后总结:
优:能较快的反应出使用动态规划解决问题,且大致结构正确
差:掌握仍不熟练,对于变量的范围,数组的容量把握的不够精准