在做树的问题时,发现一类问题很相似,他们都是可以使用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
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;
}
}