LeetCode.96 不同的二叉搜索树

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

看到题的第一反应是递归+辅助数组,并且成功做了出来,用时12ms。代码如下:

class Solution {
private:
    map<vector<int>, int> m;

    int dfs(vector<int> vec) {
        if (m.count(vec)) {
            return m[vec];
        }            

        if (vec.size() == 1) {
            return 1;
        }

        int num = 0;
        for (int i = 0; i < vec.size(); i++) {
            if (i == 0) {
                vector<int> subVec(vec.begin() + i + 1, vec.end());
                num += dfs(subVec);
            } else if (i == vec.size() - 1) {
                vector<int> subVec(vec.begin(), vec.end() - 1);
                num += dfs(subVec);
            } else {
                vector<int> preVec(vec.begin(), vec.begin() + i);
                vector<int> sufVec(vec.begin() + i + 1, vec.end());
                int num1 = dfs(preVec);
                int num2 = dfs(sufVec);
                num += (num1 * num2);
            }
        }

        m[vec] = num;
        return num;
    }
public:
    int numTrees(int n) {
        vector<int> vec(n, 0);
        for (int i = 1; i <= n; i++) {
            vec[i - 1] = i;
        }

        return dfs(vec);
    }
};   

每次做完后基本都会去查看官方题解,在看到官方题解标题为“动态规划”时,整个人都不好了,前面专项练习了那么久的动态规划,为何此题第一思路不是动态规划???
思考上面递归的思路,在每一层递归的for循环中,都有三种情况,根据此处的思路(核心思想:以vector中的某个元素为根节点,则可以生成的搜索二叉树的种类为左子树的种类数乘以右子树的种类数),写出了动态规划,以此记录,耗时0ms,记录如下:
class Solution {
public:
    int numTrees(int n) {
        vector<int> vec(n + 1, 0);
        vec[1] = 1;

        for (int i = 2; i <= n; i++) {
            int num = 0;
            for (int j = 0; j < i; j++) {
                num += vec[j] * vec[i - j - 1];
            }
            num += 2 * vec[i - 1];
            vec[i] = num;
        }
        return vec[n];
    }
};

  

posted @ 2022-01-06 10:06  太极者  阅读(44)  评论(0)    收藏  举报