[LeetCode] 1245. Tree Diameter

Given an undirected tree, return its diameter: the number of edges in a longest path in that tree.

The tree is given as an array of edges where edges[i] = [u, v] is a bidirectional edge between nodes u and v.  Each node has labels in the set {0, 1, ..., edges.length}.

Example 1:

Input: edges = [[0,1],[0,2]]
Output: 2
Explanation: 
A longest path of the tree is the path 1 - 0 - 2.

Example 2:

Input: edges = [[0,1],[1,2],[2,3],[1,4],[4,5]]
Output: 4
Explanation: 
A longest path of the tree is the path 3 - 2 - 1 - 4 - 5.

Constraints:

  • 0 <= edges.length < 10^4
  • edges[i][0] != edges[i][1]
  • 0 <= edges[i][j] <= edges.length
  • The given edges form an undirected tree.

树的直径。

给你这棵「无向树」,请你测算并返回它的「直径」:这棵树上最长简单路径的 边数。

我们用一个由所有「边」组成的数组 edges 来表示一棵无向树,其中 edges[i] = [u, v] 表示节点 u 和 v 之间的双向边。

树上的节点都已经用 {0, 1, ..., edges.length} 中的数做了标记,每个节点上的标记都是独一无二的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/tree-diameter
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

虽然题目描述是一棵树,其实这是一道图论的题目,我给出一个DFS的思路。首先我们还是建图,图建立好之后,我们用一个helper函数进行DFS遍历。对于当前某个节点的所有邻居,我们对邻居再做DFS遍历并对长度 + 1。这里我们需要利用到类似543题的思路,对于同一个node延伸出去的长度,由于我们不知道遍历的方向,所以我们记录 max1 和 max2,表示经过某个节点能组成的最大的长度和次大的长度。DFS函数在返回的时候,依然返回最长的长度max1但是对于全局变量res的更新,是res = Math.max(res, max1 + max2)。因为res本质上记录的是经过当前节点的diameter,而DFS往上一层返回的值相当于是父节点要知道到底哪个孩子返回的路径是最长的。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     int res = 0;
 3 
 4     public int treeDiameter(int[][] edges) {
 5         List<Integer>[] graph = new List[edges.length + 1];
 6         for (int i = 0; i < graph.length; i++) {
 7             graph[i] = new ArrayList<>();
 8         }
 9         for (int[] e : edges) {
10             graph[e[0]].add(e[1]);
11             graph[e[1]].add(e[0]);
12         }
13         dfs(graph, 0, -1);
14         return res;
15     }
16 
17     private int dfs(List<Integer>[] graph, int cur, int prev) {
18         List<Integer> list = graph[cur];
19         int max1 = 0;
20         int max2 = 0;
21         // 遍历每个邻居节点
22         for (int nei : list) {
23             // 防止走回头路
24             if (nei != prev) {
25                 int max = dfs(graph, nei, cur) + 1;
26                 if (max >= max1) {
27                     max2 = max1;
28                     max1 = max;
29                 } else if (max >= max2) {
30                     max2 = max;
31                 }
32                 // res记录的是经过当前节点最长的diameter是多少
33                 // 但是DFS函数返回的是当前节点能找到的最长的长度,把这个信息返回给父节点
34                 res = Math.max(res, max1 + max2);
35             }
36         }
37         return max1;
38     }
39 }

相关题目

543. Diameter of Binary Tree

1245. Tree Diameter

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/14418906.html