leetcode力扣 96题 不同的二叉搜索树 递归解法

题目描述:

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

输入输出样例

1

输入

n = 3

输出

5

提示

  • 1 <= n <= 19

思路:

​这题我使用递归,由于是二叉搜索树,也就是对于任何一个树中的节点A,左边的节点都小于A的值,右边的节点都大于A的值。那么对于一个给定的n个数字,大小不一的序列,假设我们先按照从小到大的顺序将其排列好,数字下标为0,1,2……n-1,将该序列组织成二叉搜索树,那么树根节点有n种情况,也就是0号数字作为树根,1号数字作为树根等等。

如果0号数字作为树根,那么树根的左孩子会是空,树根的右孩子看做一棵子树,这个子树一共有n-1个节点,因此0号节点作为树根(共有n个节点的二叉搜索树,其中左子节点为空)的情况数目就等于有n-1个节点的二叉搜索树的情况数目。

如果我们以1号节点作为树根,左孩子只能有0号节点,右孩子是一颗有n-2个节点的二叉搜索树,所以1号节点为树根(共有n个节点的二叉搜索树,左孩子是只有一个元素,右孩子是一颗n-2个节点的树)的情况数目就等于有n-2个节点的二叉搜索树的情况数目……

因此这就是递归,递归函数getNum(int n)是求由n个不同数字组成的二叉搜索树的情况数目,终止情况是,当n为0或者n为1。n为1,情况数目为1,n为0,要注意情况数目也为1

我们将建立一个表numTable,其中numTable[n]记录n个不同数字组成的二叉搜索树的情况数目,这是因为递归过程中可能多次调用同一个函数,查表能够更快的得到结果。该表初始都是0。

注意:

确定根节点后,我们会分别将左子树和右子树看做两颗二叉搜索树,得到左边的情况数目和右边的情况数目时,两者相乘才是总数目。

此外还要注意,n为0时,getNum(n)的值是1而不是0。

代码如下:

class Solution {
public:
    int numTrees(int n) {
        int numsTable[20] = {0}; // 作为表,记录一下
        int res = getNum(n, numsTable);
        for (int i = 0; i <= n; ++i)
            cout<<numsTable[i]<<" ";
        return res;
    }

    int getNum(int n, int* numsTable)
    {
        if (n == 1 || n == 0)
        {
            numsTable[n] = 1;
            return 1;
        }
        // 还是要递归
        int res = 0;
        for (int i = 0; i < n; ++i)
        {
            // 左边放i个
            if (numsTable[i] == 0)
                numsTable[i] = getNum(i, numsTable);
            // 右边放n-1-i个;
            if (numsTable[n-1-i] == 0)
                numsTable[n-1-i] = getNum(n-1-i, numsTable);
            res += (numsTable[i] * numsTable[n-1-i]);
        }
        numsTable[n] = res;
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_43219379/article/details/124905810