不同的二叉搜索树|刷题打卡

307 阅读3分钟

前言

今天感冒了,来打个卡!!! 本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

题目:

给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?

image.png

思路

理解下概念:二叉搜索树,昨天打卡的验证是否二叉搜索树中说明了,二叉搜索树中序遍历是个递增的序列,单独把每个跟节点拿出来,这个跟节点的左边节点都比跟节点值小,这个跟节点的右边节点都比跟节点的值大,且这个跟节点的左边和右边单独的子树都满足这个规律。

本题:由于1到n是递增的,那么我们任选一个点作为跟节点,其左边的是左子树,右边的是右子树,如果左子树和右子树大于两个值,那么就再找跟节点分,一直分到左右两边只有一个值,不能再分成子树。 举例:比如我用[1,2,3,4,5]构建

  1. 先把1当做跟节点,那么左边是没有值的[],左边记为f(0)=1,注意我们把f(0)=1认为左边没有子树也是一种null的情况为1种情况,右边是[2,3,4,5]为右子树,右子树一共多少种我现在还不知道,因为右边可以再分。我们把右边记为f(4),第一步:我们要求多少种情况为f(n)=f(0)*f(4)
  2. 把2当做跟节点,那么左子树为[1],右子树为[3,4,5],左边的当序列长度为 1时(只有根)和null的时候是一样的都只有一种情况左边f(1)=1,右边[3,4,5]那么第二步:有多少种情况为f(n)=f(1)*f(3),补充下为啥是相乘,举例:左1右3 ,左1右4,左1右5。一共多少这不就是左边乘以右边吗?
  3. 当3作为跟节点,那么左边就是[1,2],右边是[4,5]。那么同上的道理左右一共多少种情况就是f(n)=f(2)*f(2)
  4. 当4作为跟节点,那么左边就是[1,2,3],右边是[5]。那么同上的道理左右一共多少种情况就是f(n)=f(3)*f(1)
  5. 当5作为跟节点,那么左边就是[1,2,3,4],右边是[]。那么同上的道理左右一共多少种情况就是f(n)=f(4)*f(0)。 那么总的情况就是上面五步相加:f(5)=f(0)*f(4)+f(1)*f(3)+f(2)*f(2)+f(3)*f(1)+f(4)*f(0) 神奇的事情发生了:每一项的值左边和右边相加都是n-1,左边从0到n-1递增,右边从n-1到0递减
  6. 已知f(0)=1f(1)=1
  7. f(2)=f(0)*(1)+f(1)*f(0)
  8. f(3)=f(0)*(2)+f(1)*f(1)+f(2)*f(0) 那么f(4)....f(n-1)每后一项可以用前面一步的值算出来,一直往后推f(n)就是结果。。。打完收工!!!

AC代码

public int numTrees(int n) {
        int[] dp=new int[n+1];
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<=n;i++){
           for(int j=1;j<=i;j++){
               dp[i]+=dp[j-1]*dp[i-j];
           }
        }
        return dp[n];
    }

总结

所有的复杂问题都可以找规律拆分成简单重复的问题,永远记住计算机就只会循环,判断,跳出人的跳跃思维去搞算法!!!道理我都懂!动态规划我还是不会!!!