LeetCode 95. Unique Binary Search Trees II&96. Unique Binary Search Trees--动态规划,二叉树

题目链接

96. Unique Binary Search Trees

Given n, how many structurally unique BST's (binary search trees) that store values 1...n?

For example,
Given n = 3, there are a total of 5 unique BST's.

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

解:数组dp[n]代表存储1...n的异构BST的个数,根节点有n种情况,分别考虑左右子树,根节点为1时,有dp[0]*dp[n-1]个(dp[0] = 1),根节点为2时,有dp[1]*dp[n-2]个,...,根节点为n时,有dp[n-1]*dp[0]个,代码:

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


题目链接

95. Unique Binary Search Trees II

Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n.

For example,
Given n = 3, your program should return all 5 unique BST's shown below.

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3
解:看到函数的定义可知是将所有BST的根节点放在一个vector中返回,定义一个vector<vector<TreeNode*> > dp;  dp[n]依然能够由dp[0]...dp[n-1]得到,需要额外写一个copy函数,作用是树的复制,另外复制的同时可以将每个节点同时加上一个值,比如得到dp[n]时,当根节点是3,其右孩子就是dp[n-3]每个节点加上3,代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* copy(TreeNode* input, int num) {
        if (input == NULL) return NULL;
        TreeNode* output = new TreeNode(input->val+num);
        TreeNode* left = copy(input->left, num);
        TreeNode* right = copy(input->right, num);
        output->left = left;
        output->right = right;
        return output;
    }
    vector<TreeNode*> generateTrees(int n) {
        vector<vector<TreeNode*> > dp;
        vector<TreeNode*> first;
        if(n == 0) return first;
        TreeNode* temp = NULL;
        first.push_back(temp);
        dp.push_back(first);
        TreeNode* temp1 = new TreeNode(1);
        vector<TreeNode*> second;
        second.push_back(temp1);
        dp.push_back(second);
        for (int j = 2; j <= n; j++) {
            vector<TreeNode*> i;
            for (int t = 1; t <= j; t++) {
                int sizeRight = dp[j-t].size();
                int sizeLeft = dp[t-1].size();
                for (int l = 0; l < sizeLeft; l++) {
                    for (int r = 0; r < sizeRight; r++) {
                        TreeNode* temp = new TreeNode(t);
                        temp->right = copy(dp[j-t][r], t);
                        temp->left = copy(dp[t-1][l], 0);
                        i.push_back(temp);
                    }
                }
            }
            dp.push_back(i);
        }
        return dp[n];
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值