【二叉树-最长路径系列(任意路径)】直径、最长同值路径、 最大路径和(DFS、树形DP)
总述
- 这类题目都是求一个最长路径,这个路径可以不经过根节点。
- 使用dfs(即递归地遍历树)的方法。维护一个全局最长路径max作为最终结果,而递归方法dfs返回的是含根节点的最长路径。(若不使用全局变量,也可将返回类型构造自定义类,如题目124的代码2)
- 注意题目是求路径(两点之间一条线)与节点数的区别,
- 决定+1之类的细节
- 决定dfs的递归终止是null节点还是叶子结点(若是叶子结点,当到叶子结点,要控制不进入null结点)。
- 另外,求不经过根节点的最长路径一定是全部节点都要遍历,不存在剪枝情况,所以dfs不要放到if语句中。
- 另附树形DP的思想:满足"依次求出每一个节点为根节点的二叉树的子树上的最大距离,那么最终答案一定在其中",所以可以使用树形dp。
详细分析步骤按树形dp步骤来即可,简单。
题目 543. 二叉树的直径
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。
代码
class Solution {
private int maxLen=0;
public int diameterOfBinaryTree(TreeNode root) {
if(root==null){return 0;}
getTreeHeight(root);
return maxLen;
}
private int getTreeHeight(TreeNode root){
if(root.left==null&&root.right==null){
return 0;
}
int leftHeight=root.left==null?0:getTreeHeight(root.left)+1;
int rightHeight=root.right==null?0:getTreeHeight(root.right)+1;
maxLen=Math.max(maxLen,leftHeight+rightHeight);
return Math.max(leftHeight,rightHeight);
}
}
题目 687. 最长同值路径
给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。
注意:两个节点之间的路径长度由它们之间的边数表示。
题解
增加判断,若左孩子与当前节点值不同,则清左边最大同值路径长度=0;右孩子同理。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private int maxLen=0;
public int longestUnivaluePath(TreeNode root) {
if(root==null){return 0;}
dfs(root);
return maxLen;
}
private int dfs(TreeNode root){
if(root.left==null&&root.right==null){
return 0;
}
int leftMaxLen=root.left==null?0:dfs(root.left)+1;//因为所有路径都要遍历到,所以不能有剪枝操作,所以dfs不能放到if里面去。
if(root.left!=null&&root.left.val!=root.val){
leftMaxLen=0;
}
int rightMaxLen=root.right==null?0:dfs(root.right)+1;
if(root.right!=null&&root.right.val!=root.val){
rightMaxLen=0;
}
maxLen=Math.max(maxLen,leftMaxLen+rightMaxLen);
return Math.max(leftMaxLen,rightMaxLen);
}
}
题目 124. 二叉树中的最大路径和
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
题解
与上两题不同,这题是求节点和,所以当和为负,要更新为0;
代码
class Solution {
private int max = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxRootPathSum(root);
return max;
}
private int maxRootPathSum(TreeNode root){
if(root==null){return 0;}
int leftMaxVal=Math.max(0,maxRootPathSum(root.left));
int rightMaxVal=Math.max(0,maxRootPathSum(root.right));
max=Math.max(max,leftMaxVal+rightMaxVal+root.val);
return Math.max(leftMaxVal,rightMaxVal)+root.val;
}
}
代码2 返回类型使用构造类,代替类变量
class Type{
int maxDis;
int treeHeight;
public Type(int maxDis,int treeHeight) {
this.maxDis=maxDis;
this.treeHeight=treeHeight;
}
}
public class Main {
public static void main(String args[]) {
//test
Node n1=new Node(1);
Node n2=new Node(2);
Node n3=new Node(3);
Node n4=new Node(4);
Node n5=new Node(5);
n1.left=n2;
n1.right=n3;
n3.left=n4;
n3.right=n5;
int maxDis=maxDistance(n1).maxDis;
System.out.println(maxDis);
}
public static Type maxDistance(Node root) {
if(root==null) {
return new Type(0,0);
}
Type lMes=maxDistance(root.left);
Type rMes=maxDistance(root.right);
int disTemp=lMes.treeHeight+rMes.treeHeight+1;
int maxDis=Math.max(Math.max(lMes.maxDis, rMes.maxDis), disTemp);
int height=Math.max(lMes.treeHeight, rMes.treeHeight)+1;
return new Type(maxDis,height);
}
}
posted on 2019-08-07 23:45 coding_gaga 阅读(953) 评论(0) 编辑 收藏 举报