美文网首页
Java 算法-不同的二叉查找树I和II(动态规划和深搜算法)

Java 算法-不同的二叉查找树I和II(动态规划和深搜算法)

作者: 琼珶和予 | 来源:发表于2018-01-11 09:55 被阅读0次

  二叉查找树在数据结构中学习,但是感觉自己学的非常水,最近在lintCode上做了两道的关于二叉查找树的题,感觉有比较记录下来,就当是增强记忆!

1.二叉查找树I

题意:
给出 n,问由 1...n 为节点组成的不同的二叉查找树有多少种?
样例:
给出n = 3,生成所有5种不同形态的二叉查找树:

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

  这个是数据结构中的二叉树中非常的常见。这个是典型卡特兰数的样例

(1).卡特兰数

  令h(0)=1,h(1)=1,卡特兰数满足递归式:h(n) = h(0)h(n-1) + h(1)h(n-2) + ... + h(n-1)*h(0) (n>=2);该递推公式为:h(n) = C(2n,n)/(n+1),n=0,1,2,3,...

(2).为什么二叉查找树满足卡特兰数呢?

  我们这样来假设
  当只有一个节点时,肯定只有一种情况,我们于是假设f(1) = 1;
  当只有两个节点时,怎么来考虑?我们固定一个节点,另一个节点要么放在左子树,要么放在右子树,所以分为两种情况,f(2) = f(1) + f(1)。其中的f(1),我们这样来理解,第一个f(1)实际上是f(1) * f(0)(这里的f(0)等于1,为什么f(0)等于1呢?因为没有节点也只有一种情况啊!),表示意思是,左子树只有一个节点,右子树没有节点,而第二个f(1)表示为f(0) * f(1),表示的是左子树没有节点,右子树只有一个节点。
  当只有三个或者三个节点以上时,我们假设为n, f(n)的情况就分为左子树为0并且右子树为n - 1(因为有一个节点被固定了,所以只有n - 1个节点),左子树为1并且右子树为n - 2,左子树为2并且右子树为 n - 3等等...然后我们就可以退出公式:f(n) = f(0) * f(n - 1) + f(1) * f(n - 2) + ...... + f(n - 2) * f(1) + f(n - 1) * f(1)。

(3).动态规划

  根据上面的递归公式,我们可以写出动态规划的代码

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

2.二叉查找树II

题意:
给出n,生成所有由1...n为节点组成的不同的二叉查找树
样例:
给出n = 3,生成所有5种不同形态的二叉查找树:

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

  说实话,这道题真的不知道怎么写,标签上写的是深搜,但是就是不知道怎么写出来,因为之前只写过深搜的搜索题,没有做过深搜的生成类型题!
  最后我在网络上找的别人的代码,然后理解了,也不知道理解的是否正确。
  先来看看代码

public List<TreeNode> generateTrees(int n) {
        List<TreeNode> list = new ArrayList<>();
        if(n < 0) {
            return null;
        }
        list = createTree(1, n);
        return list;
    }

    private List<TreeNode> createTree(int start, int end) {
        List<TreeNode> list = new ArrayList<>();
        if (start > end) {
            list.add(null);
            return list;
        }
        for (int i = start; i <= end; i++) {
            List<TreeNode> left = createTree(start, i - 1);
            List<TreeNode> right = createTree(i + 1, end);
            for (int j = 0; j < left.size(); j++) {
                for (int k = 0; k < right.size(); k++) {
                    TreeNode node = new TreeNode(i);
                    node.left = left.get(j);
                    node.right = right.get(k);
                    list.add(node);
                }
            }
        }
        return list;
    }

  我是这样理解的:比如n个节点,它有分为n - 1种情况,跟上面的卡特兰数一样,然后我们分别构造当前节点的左子树和右子树,通过递归来构造。由于有n - 1种情况,所以得有一个循环来构造。

相关文章

  • Java 算法-不同的二叉查找树I和II(动态规划和深搜算法)

      二叉查找树在数据结构中学习,但是感觉自己学的非常水,最近在lintCode上做了两道的关于二叉查找树的题,感觉...

  • 二叉搜索树

    二叉搜索树 图解二叉树搜索算法图解:二叉搜索树算法二叉查找树(Binary Search Tree),(又:二叉搜...

  • 高频题

    字符串 数学 数组 二叉树 二分查找 链表 动态规划 贪心算法 堆 广度优先搜索 深度优先 哈希表 回溯算法 设计

  • 音视频开发之旅(27) 算法序列 - 二叉查找树

    目录 常见的查找数据结构和算法介绍 二叉查找树 资料 收获 一、常见的查找数据结构和算法介绍 1.1 链表(顺序查...

  • Algorithm小白入门 -- 二叉树

    二叉树二叉树构造二叉树寻找重复子树 1. 二叉树 基本二叉树节点如下: 很多经典算法,比如回溯、动态规划、分治算法...

  • 查找

    静态查找顺序查找 折半查找 散列查找 动态查找二叉排序树 散列查找 ASL(平均查找长度) - 衡量查找算法效率的...

  • 树表查找算法

    最简单的树表查找算法——二叉树查找算法 基本思想 二叉查找树是先对待查找的数据进行生成树,确保树的左分支的值小于右...

  • 算法学习收藏

    动态规划问题 动态规划(最优子结构和重叠子问题的比较) 动态规划解决01背包问题 01背包问题 最优二叉查找树 《...

  • 算法学习笔记——贪心算法

    动态规划和贪心算法的相同点和不同点 相同点:动态规划和贪心算法的都是一种递推算法,都是由局部最优解来推导全局最优解...

  • 每日Leetcode—算法(11)

    110.平衡二叉树 算法: 111.二叉树的最小树深 算法: 112.路径总和 算法:

网友评论

      本文标题:Java 算法-不同的二叉查找树I和II(动态规划和深搜算法)

      本文链接:https://www.haomeiwen.com/subject/pokznxtx.html