给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。
注意:两个节点之间的路径长度由它们之间的边数表示。
示例 1:
输入:
输出:
2
示例 2:
输出:
2
——————
解题思路:要知道通过根节点的最长同值路径,需要知道以左子节点为根的左半边子树的同值的最长路径
n
u
m
(
r
o
o
t
−
>
l
e
f
t
)
num(root->left)
num(root−>left)和以左子节点为根的右半边子树的同值的最长路径
n
u
m
(
r
o
o
t
−
>
r
i
g
h
t
)
num(root->right)
num(root−>right),选择其中的最长路径
m
a
x
(
n
u
m
(
r
o
o
t
−
>
l
e
f
t
)
,
n
u
m
(
r
o
o
t
−
>
r
i
g
h
t
)
)
max(num(root->left),num(root->right))
max(num(root−>left),num(root−>right))。
如果左子节点和根节点的值一样,则根节点的左子树的最长同值路径长度为 n u m ( r o o t − > l e f t ) + 1 num(root->left)+1 num(root−>left)+1,否则根节点的同值左子树的长度变为0。
同理,对于根节点的右子结点,如果根节点和根节点的右子节点的值一样,则根节点的右子树的最长同值路径长度为 n u m ( r o o t − > r i g h t ) + 1 num(root->right)+1 num(root−>right)+1,否则根节点的同值右子树的长度变为0。
根据得到的根节点的同值左子树的长度和根节点的同值右子树的长度可以计算得到经过根节点的最长同值路径的长度。
因此,我们设计的递归函数需要维护一个在二叉树中的最长同值路径的长度的变量,同时需要维护一个对于某个节点,其最长左子树的长度和最长右子树的长度的变量。
其C++代码如下,时间复杂度为 O ( n ) O(n) O(n),n为二叉树中节点的个数,空间复杂度为 O ( H ) O(H) O(H),H为二叉树中树的高度。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
int res = 0; //变量用于村存储二叉树中的最长同值路径
public:
int longestUnivaluePath(TreeNode* root) {
function(root);
return res;
}
int function(TreeNode* root)
{
if(root==NULL) // 如果当前节点为NULL,返回0
return 0;
int left = function(root->left); // 计算当前节点的左子节点的最长左子树(最长右子树)的值,并取两者之间的最大值
int right = function(root->right); // 计算当前节点的右子节点的最长左子树(最长右子树)的值,并取两者之间的最大值
if(root->left!=NULL && root->val == root->left->val) // 判断左子节点和根节点的值是否一样
left = left + 1;
else
left = 0;
if(root->right!=NULL && root->val == root->right->val) // 判断右子节点和根节点的值是否一样
right = right + 1;
else
right = 0;
res = max(res, left + right); // 更新经过根节点的最长同值路劲的长
return max(left,right); // 返回根节点的左右子树的两个同值路径中的较大那个的长度。
}
};