找到含有节点最多 的搜索二叉子树

题目:有一棵二叉树,其中所有节点的值都不一样,找到含有节点最多 的搜索二叉子树,并返回这棵子树的头节点.

给定二叉树的头结点root,请返回所求的头结点,若出现多个节点最多的子树,返回头结点权值最大的。

Java代码:

import java.util.*;

/*

public class TreeNode {

    int val = 0;

    TreeNode left = null;

    TreeNode right = null;

    public TreeNode(int val) {

        this.val = val;

    }

}*/

public class MaxSubtree {

    public TreeNode getMax(TreeNode root) {

        /*

        以root为头的树,最大的搜索子树只能来自以下两种情况:

        情况一:root为头的树整棵都是最大搜索二叉树,node左子树的最大搜索二叉树的最大值小于node节点值,node右子树的最大

        搜索二叉树的最小值大于node节点值

        情况二:不满足情况一,那么最大搜索二叉树的节点数就是node左子树上的最大搜索二叉树和node右子树上的最大搜索二叉树中

        节点数较多的那个

        1.整个过程是后序遍历

        2.遍历到的当前节点为cur,先遍历cur的左子树并收集3个信息,分别是左子树上最大搜索二叉树的节点数,树上最大数,树上

        最小数。再遍历cur的右子树同样记录3个值,节点数,树上最大数,树上最小数。

        3.根据2收集的信息判断是否满足情况一,满足1的话就返回cur节点.否则满足情况2,返回左节点数和右节点数中较大的数的节点

        */

        int[] record=new int[3];

        return pos(root,record);

    }

    public TreeNode pos(TreeNode root,int[]record)

        {

        if(root==null)

            {

            record[0]=0;

            record[1]=Integer.MIN_VALUE;

            record[2]=Integer.MAX_VALUE;

            return null;

        }

        TreeNode left=pos(root.left,record);

        int lsize=record[0];//节点数

        int lmax=record[1];//左子树上最大搜索二叉树的最大值

       int lmin=record[2];//左子树上最大搜索二叉树的最小值

        TreeNode right=pos(root.right,record);

        int rsize=record[0];

        int rmax=record[1];

        int rmin=record[2];

       if(left==root.left&&right==root.right)

            {

            if(left==null&&right==null)//左右子树为空的情况要考虑,不然结果为null

               {

            record[0]=1;

            record[1]=root.val;

            record[2]=root.val;

            return root;

           }

           if(lmax<root.val&&rmin>root.val)

                {

             record[0]=lsize+rsize+1;

            record[1]=Math.max(rmax,root.val);

            record[2]=Math.min(lmin,root.val);

            return root;

            }

          

        }

            if(lsize>rsize||(lsize == rsize&& left.val >= right.val))//后一种为节点树相同时

                {

                record[0]=lsize;

                record[1]=lmax;

                record[2]=lmin;

                return left;

            }

        else if(lsize < rsize || (lsize == rsize && left.val <right.val))

                {

                record[0]=rsize;

                record[1]=rmax;

                record[2]=rmin;

                return right;

            }

            

                return root;

    }

}

//另一种写法

import java.util.*;

/*

public class TreeNode {

    int val = 0;

    TreeNode left = null;

    TreeNode right = null;

    public TreeNode(int val) {

        this.val = val;

    }

}*/

public class MaxSubtree {

    public TreeNode getMax(TreeNode root) {

        /*

        以root为头的树,最大的搜索子树只能来自以下两种情况:

        情况一:root为头的树整棵都是最大搜索二叉树,node左子树的最大搜索二叉树的最大值小于node节点值,node右子树的最大

        搜索二叉树的最小值大于node节点值

        情况二:不满足情况一,那么最大搜索二叉树的节点数就是node左子树上的最大搜索二叉树和node右子树上的最大搜索二叉树中

        节点数较多的那个

        1.整个过程是后序遍历

       2.遍历到的当前节点为cur,先遍历cur的左子树并收集3个信息,分别是左子树上最大搜索二叉树的节点数,树上最大数,树上

        最小数。再遍历cur的右子树同样记录3个值,节点数,树上最大数,树上最小数。

        3.根据2收集的信息判断是否满足情况一,满足1的话就返回cur节点.否则满足情况2,返回左节点数和右节点数中较大的数的节点

        */

        int[] record=new int[3];

        return pos(root,record);

    }

    public TreeNode pos(TreeNode root,int[]record)

        {

        if(root==null)

            {

            record[0]=0;

            record[1]=Integer.MIN_VALUE;

            record[2]=Integer.MAX_VALUE;

            return null;

        }

        TreeNode left=pos(root.left,record);

        int lsize=record[0];//节点数

        int lmax=record[1];//左子树上最大搜索二叉树的最大值

        int lmin=record[2];//左子树上最大搜索二叉树的最小值

        TreeNode right=pos(root.right,record);

        int rsize=record[0];

        int rmax=record[1];

        int rmin=record[2];

        record[1]=Math.max(rmax,root.val);

        record[2]=Math.min(lmin,root.val);

       if(left==root.left&&right==root.right&&lmax<root.val&&rmin>root.val)

            {

             record[0]=lsize+rsize+1;

            return root;

          

        }

           record[0]=Math.max(lsize,rsize);

        return lsize>rsize?left:right;

    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值