1245. Tree Diameter
解题思路:本题是一道图的题目,但是无向图,给定的输入是图的各个边,题目中给出一个关键信息(Each node has labels in the set {0, 1, ..., edges.length})可知
图中没有环,如果是有环的图这个题是无解的。最好的证明方法就是反正法,如果有环的话标号最大的节点必然小于边的数量,例如[0, 1], [1, 2], [0, 2], 三个节点且三条边,但编号最大的节点小于边的数量。
题目的解法依然是在图上做dfs寻找答案,因为是无向图,对于一个节点来说,可以从任何一个边进入,而从另外的边出去(除去只有一个边的节点,可以称为叶子节点),对于不同的入边,返回的答案是不一样的,对于已经计算过的从当前节点出去的边的最大长度也需要保存起来。
class Solution { public: int recursive(vector<vector<int>>& graph, vector<map<int, int>>& memo, vector<bool>& visited, int cur){ int len = 0; for(int i = 0; i < graph[cur].size(); ++i){ int next = graph[cur][i]; if(!visited[next]){ visited[next] = true; if(memo[cur][next] == 0){ memo[cur][next] = recursive(graph, memo, visited, next) + 1; } len = max(len, memo[cur][next]); } } return len; } int treeDiameter(vector<vector<int>>& edges) { const int nodeCnt = edges.size() + 1; vector<vector<int>> graph(nodeCnt, vector<int>()); vector<map<int, int>> memo(nodeCnt, map<int, int>()); for(auto edge : edges){ graph[edge[0]].push_back(edge[1]); graph[edge[1]].push_back(edge[0]); memo[edge[0]][edge[1]] = 0; memo[edge[1]][edge[0]] = 0; } int ans = 0; for(int i = 0; i < graph.size(); ++i){ if(graph[i].size() == 1){ vector<bool> visited(nodeCnt, false); visited[i] = true; ans = max(ans, recursive(graph, memo, visited, i)); } } return ans; } };