二叉搜索树

二叉搜索树

LC.96 不同的二叉搜索树

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 + 1;++i){
            for(int j = 1;j <= i;++j){
                G[i] += G[j - 1]*G[i - j];
            }
        }
        return G[n];

    }
}

动态规划:遍历数组的每一个数字 i,将其作为树的根。则 i 左边的序列构成其左子树,右边的序列构成右子树。然后我们可以递归地构建左右子树。

设G(n):长度为n的序列能构成的不同二叉搜索树的个数。

F(i,n):以 i 为根节点,长度为n的序列能构成的不同二叉搜索树的个数。

则:
G ( n ) = ∑ i = 1 n F ( i , n ) G(n) = \sum_{i =1}^{n}F(i,n) G(n)=i=1nF(i,n)
即以 i 为根节点的BST个数等于 i 左边序列构成的BST个数乘以 i 右边序列构成的BST个数。将 i 从1遍历到n即为结果。

LC.95 不同的二叉搜索树(2)

class Solution {
    public List<TreeNode> generateTrees(int n) {
        if(n == 0){
            return new LinkedList<TreeNode>();
        }
        return getTree(1,n);


    }
    public List<TreeNode> getTree(int start,int end){
        List<TreeNode> ans = new LinkedList<TreeNode>();
        if(start > end){
            ans.add(null);
            return ans;
        }
        for(int i = start;i <= end;i++){
            List<TreeNode> leftTrees = getTree(start,i-1);
            List<TreeNode> rightTrees = getTree(i+1,end);
           for(TreeNode left : leftTrees){
               for(TreeNode right : rightTrees){
                   TreeNode cur = new TreeNode(i);
                   cur.left = left;
                   cur.right = right;
                   ans.add(cur);
               }
           }
        }
        return ans;
        
    }
}

用递归的思想解题,一定要明确递归函数的定义,并相信这个定义,不要过多地考虑递归实现的细节。这里递归函数的作用是得到从1到n的序列组成的所有BST。那么我继续调用这个函数分别得到 i 的左边序列和右边序列构成的BST并进行拼接和储存即可。最后不要忘记考虑base case!

LC.99 恢复二叉搜索树

class Solution {
    TreeNode t1,t2,pre;
    public void recoverTree(TreeNode root) {
        inorder(root);
        int tem = t1.val;
        t1.val = t2.val;
        t2.val = tem;
    }
    public void inorder(TreeNode root){
        
        if(root == null){
            return;
        }
        inorder(root.left);
        if(pre != null && pre.val > root.val){
            if(t1 == null) t1 = pre;//确保t1只被标记一次
            t2 = root;
        } 
        pre = root;
        inorder(root.right);
    }
}

关键在于找到两个错位的节点,最后再进行交换即可。BST的一个重要性质是它的中序遍历结果是有序(从小到大)的,我们可以利用这一性质找到错位的节点。在出现下降趋势的时候(也就是有错误点的时候),同时记录 pre 和当前点。如果两个错误点相邻,那么就完成了;如果不相邻,在后面再出现错误点时就会覆盖掉原来记录的第二个点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的高校科研信息管理系统实现了操作日志管理、字典管理、反馈管理、公告管理、科研成果管理、科研项目管理、通知管理、学术活动管理、学院部门管理、科研人员管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让高校科研信息管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值