题目要求

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

返回用1-n这n-1个数字可以构成的全部搜索二叉树以及其个数。

思路和代码

如果只是单纯的计算二叉树的数量,其实这就完全转化成了一道规律题。我们可以从1开始寻找规律。
1: 1
1,2: 12, 21
1,2,3:123,132,213,312,321

我们可以通过dp的方式来记录。无论以哪一个节点作为root节点,它的左子树的元素和右子树的元素都是固定的。也就是说,假设root值为i,那么左子树的元素为[1...i-1],右子树的元素为[i+1...n]。因此当前root节点可以生成的平衡二叉树数量即为左子树数量*右子树数量。在这里我们使用int[]数组中下标为n的位置来记录n个元素可以组成的平衡二叉树的数量

    public int numTrees(int n) {
        int[] nums = new int[n+1];
        for(int i = 0 ; i <= n ; i++){
            if(i==0 || i==1) nums[i] = 1;
            else{
                for(int j = 1 ; j<=i ; j++){
                    nums[i] += nums[j-1]*nums[i-j];
                }
            }
        }
        return nums[n];
    }

如果要我们返回具体树的形态的话,就需要我们通过backtracking的递归形式来找到所有的平衡二叉树。在递归的过程中,我们找到以当前节点作为根节点的所有平衡二叉树,并将结果以list形式返回上一级调用。

    public List<TreeNode> generateTrees(int n) {
        if(n==0) return new ArrayList<TreeNode>();
        return generateTrees(1,n);
    }
    public List<TreeNode> generateTrees(int start, int end){
        List<TreeNode> result = new ArrayList<TreeNode>();
        if(start>end){
            result.add(null);
        }else if(start==end){
            result.add(new TreeNode(start));
        }else{
            for(int i = start ; i<=end ; i++){
                List<TreeNode> left = generateTrees(start, i-1);
                List<TreeNode> right = generateTrees(i+1, end);
                for(TreeNode tempLeft : left){
                    for(TreeNode tempRight : right){
                        TreeNode root = new TreeNode(i);
                        root.left = tempLeft;
                        root.right = tempRight;
                        result.add(root);
                    }
                }
            }
            
        }
        return result;
        
    }

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~


raledong
2.7k 声望2k 粉丝

心怀远方,负重前行