Tree Longest Path With Same Value -LintCode

来源:互联网 发布:淘宝网店转让流程 编辑:程序博客网 时间:2024/06/06 05:01

假设有一棵有 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]
描述了下面的这棵树:

                   1value = 1)                 /   \    (value = 1) 2     3 (value = 1)               /  \ (value = 2)  4     5 (value = 2)

你写的程序需要返回 2,因为最长路径为 2 -> 1 -> 3(所有节点的值均为1)。这条路径的边的数量为 2,所以答案是 2

思路:
刚开始想着由依赖关系构成树,找到根节点,由此转化为求树的最长相同值路径。
出错,才发现依赖关系只是相连无法找到根节点构成树。

#ifndef C717_H#define C717_H#include<iostream>#include<vector>#include<algorithm>using namespace std;class Solution {public:    /*    * @param : as indicated in the description    * @param : 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);        vector<int> v(A.size(), 0);        for (int i = 0; i < E.size(); i = i + 2)        {            nums[E[i]].push_back(E[i + 1]);            v[E[i + 1]-1] = 1;        }        int root = 0;        for (int i = 0; i < A.size(); ++i)        {            if (v[i] == 0)                root = i + 1;        }        int num = 0;        CountPath(nums, A, root, num);        return num;    }    int CountPath(vector<vector<int>> nums, vector<int> A, int root, int &res)    {        if (nums[root].size() == 0)            return 0;        vector<int> tmp(nums[root].size(), 0);        for (int i = 0; i < nums[root].size(); ++i)        {            tmp[i] = CountPath(nums, A, nums[root][i], res);        }        for (int i = 0; i < nums[root].size(); ++i)        {            if (A[root - 1] == A[nums[root][i] - 1])                tmp[i] = tmp[i] + 1;            else                tmp[i] = 0;        }        sort(tmp.begin(), tmp.end());        if (nums[root].size() == 1)            res = maxVal(res, tmp[0]);        else            res = maxVal(res, tmp[nums[root].size() - 1] + tmp[nums[root].size() - 2]);        return tmp.back();    }    int maxVal(int a, int b)    {        return a > b ? a : b;    }};#endif

之后,利用深度搜索,先对相连接的节点构建双向映射,递归地计算出当前节点的最长相同值路径,
最后得到结果。

#ifndef C717_H#define C717_H#include<iostream>#include<vector>#include<map>#include<algorithm>using namespace std;class Solution {public:    /*    * @param : as indicated in the description    * @param : 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 = maxVal(res, tmp[tmp.size()-1] + tmp[tmp.size() - 2]);        return tmp.back();//如果路径还要加上父节点,则选择子节点中值最大的那个    }    int maxVal(int a, int b)    {        return a > b ? a : b;    }};#endif
原创粉丝点击