问题一:二叉树中最大路径和(leetcode124)
问题描述:
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
大体思路:
其最大路径和有以下四种可能:
1) 由当前结点的左子树结点到右子树结点
2) 由当前结点到其左子树某一节点
3) 由当前结点到其右子树某一节点
4) 由当前结点本身
分析完可能性发现不能简单的返回当前结点的最大路径和,对于子节点是情况一而言,父节点拿到子结点的路径和没有一点作用。因此我们使用一全局变量存储最大路径和,遍历时返回以该节点出发的最大路径(有点类似二叉树的深度)由于是任意结点出发到任意节点,因此若当前结点的最大路径小于0时返回值应该为0(表示可以不往下走了)。
实现代码如下:
class Solution {
int ans = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
process(root);
return ans;
}
public int process(TreeNode root){ // 返回从root出发的最大路径和
if(root == null){
return 0;
}
int left = process(root.left);
int right = process(root.right);
ans = Math.max(ans, root.val + left + right);
return Math.max(0, Math.max(root.val + right, root.val + left));
}
}
问题二:最长同值路径(leetcode687)
问题描述:
给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。
注意:两个节点之间的路径长度由它们之间的边数表示。
大体思路:
由于都是路径和问题,与问题一的四种可能性相同。
使用一全局变量存储最大的同值路径和。
遍历时返回以当前结点出发的最大同值路径和length。
当前节点拿到左右孩子的length时,会判断其左右孩子是否与当前结点值相同,若相同其的length为左右孩子中长度最大的加1;经过当前结点的最大路径长度为左右孩子长度 + 1之和。
实现代码如下:
class Solution {
public int ans = 0;
public int longestUnivaluePath(TreeNode root) {
process(root);
return ans;
}
public int process(TreeNode root){ // 返回以当前结点的值路径的长度
if(root == null){
return 0;
}
int sum = 0;// 经过当前结点的最大同值路径和
int length = 0; // 从当前结点出发的最大同值路径和
int left = process(root.left);
int right = process(root.right);
if(root.left != null && root.val == root.left.val){
sum += left + 1;
length = left + 1;
}
if(root.right != null && root.val == root.right.val){
sum += right + 1;
length = Math.max(length, right + 1);
}
ans = Math.max(ans, sum);
return length;
}
}