[算法系列]递归应用——二叉树(2):一种带信息递归返回的求解方式

[算法系列]递归应用——二叉树(2):一种带信息递归返回的求解方式

本文是递归系列文的第七篇,和上篇文章类似,介绍BinaryTree的解题思路。这里介绍一种和“遍历”行为类似的,自下而上递归返回信息的解题思路。其规则的写法、并不复杂的思路,可解决大多bintree中与子树有关的问题(但愿吧哈哈哈)

0.引子:求二叉树节点中的最大值和最小值

此题当然可以通过遍历整棵二叉树,将遍历途中遇到的最大值和最小值进行保存。遍历完成后maxVal和minVla即为所求:

class MaxAndMinInBinTree{
   
    int maxVal = Integer.MIN_VALUE;
    int minVal = Integer.MAX_VALUE;
    public  int[] getMinMaxInBT(TreeNode node){
   
        process(node);
        return new int[]{
   maxVal, minVal};
    }
    public void process(TreeNode node){
   
        if(node == null) return;

        maxVal = Math.max(node.val , maxVal);
        minVal = Math.min(node.val, minVal);
        process(node.left);
        process(node.right);
    }
}

那么这道题目除了用 二叉树的 ”遍历“ 思路,还可以怎么想呢?

回忆我们求二叉树的高度时用到的思路:

  1. 当前子树的高度 =max( 左子树的高度 ,右子树高度)+ 1
  2. 在递归中逐渐返回到头结点:树的高度 = max(根的子树高度,根的右子树高度) +1

这其实就是一种和遍历思路稍显区别的,俺将其命名为带信息返回的求解思路。那么如果将其运用到求整棵树的最大最小值时,就可以自然而然地有如下想法:

  1. 当前子树的最大值 = max(左子树最大值,右子树最大值,当前节点的值)
  2. 当前子树的最小值 = min(左子树最小值,右子树最小值,当前节点的值)
  3. 在递归中逐渐向上返回到根节点。

该思路其一般可写成如下框架:

public ReturnData process(TreeNode node){
   
    if(node == null){
   
        //处理节点为空的情况,也是”递“到达的最深处,”归“上去的起点
    }
    ReturnData leftDate = process(node.left);
    ReturnData rightData = process(node.right);
    
    return new ReturnData(
    	//根据当前节点考虑可能性,构造当前要向上返回的信息集
    )
}

下面来解释一波上述的伪代码:

  1. ReturnData是自定义的一个类,里面包含的是递归过程中每次需要返回的所有信息

  2. 看整个process函数框架,看过我前面详解递归的小伙伴应该比较清楚:node == null 实际上就是边界条件,是递归的出口,在此处我们需要拿捏最小问题的处理方式。

    紧接着,是两个递归调用process的过程,用leftData和rightData去接收左子树和右子树的结果。这一点前面也提到过:该模式下process函数会一口气走到最左下的为null的节点,然后再返回到右下,从叶节点开始,逐渐往上地返回。

    在返回过程中,构建了一个新的ReturnData实例对象。这也就把所需要返回的信息向上地”归“到了根节点。

  3. 在新构建返回信息的实例对象中,就是我们根据可能性进行构造的过程。

好了,现在看看用这个方法时怎样操作的:

class MaxAndMinInBinTree2{
   
    /* 这个题的返回信息就是所要求的最大值,最小值 */
    public static class ReturnData{
   
        public int maxVal;
        public int minVal;
        public ReturnData(int maxVal , int minVal){
   
            this.maxVal = maxVal;
            this.minVal = minVal;
        }
    }

    public void getMinMax(TreeNode node){
   
        ReturnData data = process(node);
        System.out.println(data.maxVal + "  " + data.minVal);
    }
    private ReturnData process(TreeNode head){
   
        /* 递归边界条件,构造最初的返回信息 */                                                                                            */
        if(head == null){
   
            return  new ReturnData(Integer.MIN_VALUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值