二叉树递归之几个相似问题的分析--在递归树的时候统计树的某种特征

题型归纳总结

在做树的问题时,发现一类问题很相似,他们都是可以使用dfs的方法,对树进行递归遍历,并计算某种树的统计值(也就是树的某种特征值,)

  • dfs递归左右子树得到左子树和右子树的某种计算值(通常是深度或者其他需要符合题意的计算结果)
  • 统计的特征值往往是基于左子树和右子树的计算值,综合二者进行计算,在递归的过程中往往需要更新一个全局变量来满足题目要求的求最x值

难点是:往往被递归绕进去,在做树的递归的时候,我们可以将树简单的看成,左子树右子树,分析出递归要求的是什么?递归的终止条件是什么?

二叉树的直径

leetCode543:二叉树的直径

  • 首先,二叉树的直径是任意两个节点路径长度中最大值(这是定义)
  • 直径计算公式=左子树的深度+右子树的深度;那要求全局最大的一个定义一个全局变量即可
  • 递归的过程就是求树的深度的过程,在递归的过程中更新直径

package com.zj.ETree.exe;

import java.util.Map;

/**
 * @Auther Jian Zhou
 * @Date 2020/7/28
 * 二叉树的直径:
 * 给定一棵二叉树,需要计算他的直径长度;
 * 一棵二叉树的直径长度是任意两个节点路径长度中最大的值。这条路径可能穿过也可能不穿过根节点
 */
public class Problem543 {

    /**
     * @param root
     * @return
     */
    int max = Integer.MIN_VALUE;
    //计算直径长度
    public int diameterOfBinaryTree(TreeNode root) {
        if(root==null) return 0;
        dfs(root);
        return max;
    }

    /**
     * @param root
     * @return
     * 直径长度=左子树深度+右子树深度
     * 计算 子树的深度
     */
    public int dfs(TreeNode root){
        if(root==null) return 0;
        //左子树的深度
        int leftDepth = dfs(root.left);
        //右子树的深度
        int rightDepth = dfs(root.right);
        //直径长度=左子树深度+右子树的深度
        max = Math.max(leftDepth+rightDepth,max);
        //返回深度
        return Math.max(leftDepth,rightDepth)+1;
    }





}




最长同值路径

Problem687最长同值路径

  • 首先,同值路径是路径中每个节点都有相同的值
  • 同值路径机损公式=若root与左子节点相等则左子树同值路径长度+若root与右子节点相等则右子树同值路径长度
  • 递归的过程就是求树的连续的相等的同值的长度

package com.zj.ETree.exe;

import java.util.Map;

/**
 * @Auther Jian Zhou
 * @Date 2020/7/28
 */
public class Problem687 {

    /**
     * 最长同值路径
     * @param root
     * @return
     */
    int max = Integer.MIN_VALUE;
    public int longestUnivaluePath(TreeNode root) {
        if(root==null) return 0;
        dfs(root);
        return max;
    }
    /**
     * 递归求子树中相等最长额值(从左右子树中产生)
     * @param root
     * @return
     */
    public int dfs(TreeNode root){
        if(root==null) return 0;
        //这里计算得到的是左右子树的深度(连续相等的值)
        int leftDepth = dfs(root.left);
        int rightDepth = dfs(root.right);
        //这个用来计算
        int arrowLeft = 0;
        int arrowRight = 0;
        if(root.left!=null&&root.val==root.left.val){
            arrowLeft = leftDepth+1;
        }
        if(root.right!=null&&root.val==root.right.val){
            arrowRight=rightDepth+1;
        }
        max = Math.max(arrowLeft+arrowRight,max);
        return Math.max(arrowLeft,arrowRight);
    }



}





二叉树的最大路径和

二叉树的最大路径和

  • 首先,二叉树的路径和是左右子树的和+root.val
  • 路径和=左子树的和+柚子树的和+root.val

package com.zj.ETree.exe;

import java.util.Map;

/**
 * @Auther Jian Zhou
 * @Date 2020/7/28
 */
public class Problem124 {

    int maxSum = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
                if(root==null) return 0;
                dfs(root);
                return maxSum;
    }

    /**
     * 计算子树最大和
     * @param root
     * @return
     */
    public int dfs(TreeNode root){
        if(root==null) return 0;
        int leftSum = Math.max(0,dfs(root.left));
        int rightSum = Math.max(0,dfs(root.right));
        //计算包含根节点的最大和
        int returnValue = Math.max(leftSum,rightSum);
        maxSum = Math.max(maxSum,rightSum+leftSum+root.val);
        return returnValue+root.val;
    }




}


你可能感兴趣的:(leetcode刷题笔记)