链接:http://www.lintcode.com/zh-cn/problem/tree-longest-path-with-same-value/
假设有一棵有 N
个节点的无向树, 编号为 1
到 N
, 每一个节点都有一个int类型的值,不同的节点可以有相同的值。给一个长度为N
的数组A
,A[j]
表示第j + 1
个节点的值。再给一个长度为 (N - 1) * 2
的数组 E
,对于任意的 0 <= j <= N - 2
都有 E[2 * j], E[2 * j + 1]
表示节点 E[2 * j]
与节点 E[2 * j + 1]
有边相连。返回具有相同值的节点构成的最长路劲的长度,路劲的长度为路径边的数量。
注意事项
假设: 1 <= N <= 1000
样例
给出 A = [1, 1, 1 ,2, 2]
和 E = [1, 2, 1, 3, 2, 4, 2, 5]
描述了下面的这棵树:
1 (value = 1)
/ \
(value = 1) 2 3 (value = 1)
/ \
(value = 2) 4 5 (value = 2)
你写的程序需要返回 2
,因为最长路径为 2 -> 1 -> 3
(所有节点的值均为1)。这条路径的边的数量为 2
,所以答案是 2
class Solution {
public:
/**
* @param A: as indicated in the description
* @param E: as indicated in the description
* @return: Return the number of edges on the longest path with same value.
*/
int LongestPathWithSameValue(vector<int> &A, vector<int> &E) {
// write your code here
if (A.size() == 1)
return 0;
vector<vector<int>> nums(A.size()+1);
for (int i = 0; i < E.size(); i = i + 2)//对于相连的节点建立双向映射
{
nums[E[i]].push_back(E[i + 1]);
nums[E[i + 1]].push_back(E[i]);
}
int res = 0;
CountPath(nums, A, 0, 1,res);
return res;
}
//递归,root表示已经处理过得节点,cur表示正在处理的节点,res表示最长向同值路径的长度
int CountPath(vector<vector<int>> nums, vector<int> A, int root, int cur,int &res)
{
vector<int> tmp;
for (auto c : nums[cur])
{
if (c != root)
{
//如果其子结点存在且和当前节点值相同,其长度加1
if (A[c - 1] == A[cur - 1])
tmp.push_back(CountPath(nums, A, cur, c,res)+1);
else
CountPath(nums, A, cur, c,res);
}
}
//为了防止tmp为空
tmp.push_back(0);
tmp.push_back(0);
sort(tmp.begin(), tmp.end());
//利用子节点中的最大的两个值来更新res
res = max(res, tmp[tmp.size()-1] + tmp[tmp.size() - 2]);
return tmp.back();//如果路径还要加上父节点,则选择子节点中值最大的那个
}
};