leetcode 95&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

思路:分析树的构建过程,可以分为以不同值为根的情况。
比如以i为根,左子树为[1,i-1]构建的子树,右子树为[i+1,n]构建的子树,由于只需要数目那么与具体的id无关,只与树中节点个数有关。假设G[n]为n个节点的BST个数,那么,动态规划得到的公式如下:

G[n] = f(1,n) + ... +f(n,n) //f(i,n)为以i为根节点,总共有n个节点的树的个数
f(i,n) = G[i-1]*G[n-i]

这样,不难得到

public class Solution {
    public int numTrees(int n) {
       int[] G = new int[n+1];
       G[0] = 1;
       G[1] = 1;

       for(int i = 2; i<=n; i++){
           for(int j=1; j<=i;j++){
               G[i] += G[j-1]*G[i-j];
           }
       }

       return G[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

这次是需要得到所有可能的情况,之前考虑的是要将所有树放入List,当然放入只能放入头结点。之前傻不拉几的认为,所有节点都需要copy,其实并不需要,只要按照,不同的头结点遍历得到的结果同,也就是说,除了头结点,树内的其他节点都可以重用。
解法类似于上一题,不同的是,因为需要生产具体的节点,所有要给出具体的子树的节点范围。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<TreeNode> generateTrees(int n) {
       if(n==0) return  new ArrayList<TreeNode>();
       return genTrees(1,n);

    }

    public List<TreeNode> genTrees(int start, int end){
        List<TreeNode> res = new ArrayList<>();

        if(start> end){
            res.add(null);
            return res;
        }
        if(start==end){
            res.add(new TreeNode(start));
            return res;
        }

        List<TreeNode> left, right;
        for(int i = start; i<=end; i++){
            left = genTrees(start, i-1);
            right = genTrees(i+1, end);

            for(TreeNode node_l:left){
                for(TreeNode node_r:right){
                    TreeNode root = new TreeNode(i);
                    root.left = node_l;
                    root.right = node_r;
                    res.add(root);
                }
            }
        }
        return res;

    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值