Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root.
Note: The length of path between two nodes is represented by the number of edges between them.
Example 1:
Input:
5
/ \
4 5
/ \ \
1 1 5
Output:
2
Example 2:
Input:
1
/ \
4 5
/ \ \
4 4 5
Output:
2
首先我们定义一个概念,就是path的类型,我自己分为两种,跨越根节点的可以横向连接的,我们叫双边路径,只能从上而下纵向连接的,我们叫单边路径。很多题都是两种路径混在一起考虑。这个时候递归就要注意了。最直接的递归可以很简洁,如下:
class Solution {
public:
int longestUnivaluePath(TreeNode* root) {
if (!root) return 0;
int sub = max(longestUnivaluePath(root->left), longestUnivaluePath(root->right));
return max(sub, helper(root->left, root->val) + helper(root->right, root->val));
}
int helper(TreeNode* node, int parent) {
if (!node || node->val != parent) return 0;
return 1 + max(helper(node->left, node->val), helper(node->right, node->val));
}
};
就是要把单边递归单独拿出来讨论,这里的helper函数,就是返回从这个node开始,以parent为固定值的最长单边路径。但这么做效率比较低,重复的部分比较多。
这里想要增加的讨论就是,提醒自己,函数递归的过程中,返回值可以利用,有些别的reference变量也可以通过更新来利用。这里就是一个函数两种计算。代码如下:
class Solution {
public:
int longestUnivaluePath(TreeNode* root) {
int res = 0;
helper(root, res);
return res;
}
int helper(TreeNode* root, int &res) {
if (root == NULL) return 0;
int left = helper(root->left, res);
int right = helper(root->right, res);
if (root->left && root->left->val == root->val)
left++;
else left = 0;
if (root->right && root->right->val == root->val)
right++;
else right = 0;
res = max(res, left + right);
return max(left, right);
}
};
这里的helper返回的就是某个节点开始,最大的单边长度。但因为所有的双边都是两个单边组成的,我们在算完单边,返回左右里较大的那个之前,也完全可以加起来看看,此时,以这个节点为中心的双边路径该是多长,以此更新我们的res。
或者换种写法,但是一个意思,也可以写成:
class Solution {
public:
int longestUnivaluePath(TreeNode* root) {
int res = 0;
if (root) helper(root, root->val, res);
return res;
}
int helper(TreeNode* node, int parent, int &res) {
if (node == NULL) return 0;
int left = helper(node->left, node->val, res);
int right = helper(node->right, node->val, res);
res = max(res, left + right);
if (node->val == parent) return 1 + max(left, right);
return 0;
}
};
很重要的一点是,你要知道helper函数返回的到底是什么,如何在更新的过程中包含了所有情况的讨论。