题目
分析
1、这道题的一个难点是该树的表示不是以节点的方式,而是用数组表示,因此我们需要考虑转换一下该树的存储结构,这里采用邻接表的存储方式,当然也可以采用其他的储存结构。
2、思想:深度优先遍历,深度优先遍历函数返回当前节点到其左右子树最远的路径值的较大值,在树的遍历过程找到树的直径,具体细节看代码。
import java.util.*;
/*
* public class Interval {
* int start;
* int end;
* }
*/
public class Solution {
/**
* 树的直径
* @param n int整型 树的节点个数
* @param Tree_edge Interval类一维数组 树的边
* @param Edge_value int整型一维数组 边的权值
* @return int整型
*/
public int res = 0;
public int solve (int n, Interval[] Tree_edge, int[] Edge_value) {
// write code here
//采用邻接表存储树的节点和其边权重,list存储的当前节点的相邻结点及其边的权重
ArrayList<int[]>[] map = new ArrayList[n];
//初始化领接矩阵
for(int i = 0; i < n; i++) {
map[i] = new ArrayList();
}
//将树的节点信息和边的权重存储到邻接表中
for(int i = 0; i < Tree_edge.length; i++) {
//起始节点的边,存储终节点和边的权重值
map[Tree_edge[i].start].add(new int[]{Tree_edge[i].end,Edge_value[i]});
// 终节点的边,存储起节点和权重值
map[Tree_edge[i].end].add(new int[]{Tree_edge[i].start,Edge_value[i]});
}
dfs(map,0,new boolean[n]);
return res;
}
//map是邻接表,index是遍历树的开始索引,visited是访问标记
public int dfs( ArrayList<int[]>[] map,int index,boolean[] visited) {
//访问的节点不在邻接表中
if(index >= map.length) {
return 0;
}
//访问该节点
visited[index] = true;
//获取该节点的相邻结点
ArrayList<int[]> list = map[index];
//这两个变量分别保存以当前节点为起点的左右子树的最长路径
int leftWeight = 0;
int rightWeight = 0;
//
//获取相邻结点
int nextNode = num[0];
//获取边的权重
int weight = num[1];
//如果该节点已经被访问过
if(visited[nextNode]) {
continue;
}
//获取当前节点到其子树的最远距离
int totel = weight + dfs(map,nextNode,visited);
//注意这里是存储左右子树的最远距离
if(totel > leftWeight) {
rightWeight = leftWeight;
leftWeight = totel;
} else if(totel > rightWeight) {
rightWeight = totel;
}
//
if(leftWeight + rightWeight > res) {
res = leftWeight + rightWeight;
}
}
//返回包含当前节点左右子树最长路径值
return Math.max(leftWeight,rightWeight);
}
}
下面给出采用邻接矩阵存储结构的代码:
public int res = 0;
public int solve (int n, Interval[] Tree_edge, int[] Edge_value) {
//采用邻接矩阵的方式存储树
int[][] map = new int[n][n];
//初始化邻接矩阵
for(int i = 0; i < Tree_edge.length; i++) {
map[Tree_edge[i].start][Tree_edge[i].end] = Edge_value[i];
map[Tree_edge[i].end][Tree_edge[i].start] = Edge_value[i];
}
dfs(map,0,new boolean[n]);
return res;
}
public int dfs(int[][] map,int index,boolean[] visited) {
if(index >= map.length) {
return 0;
}
//访问该节点
visited[index] = true;
int leftWeight = 0;
int rightWeight = 0;
//获取该节点的相邻结点
for(int i = 0; i < map.length; i++) {
//权重值大于0,说明有相邻结点,且未被访问过
if(map[index][i] > 0 && visited[i] == false) {
int totel = map[index][i] + dfs(map,i,visited);
if(totel > leftWeight) {
rightWeight = leftWeight;
leftWeight = totel;
} else if(totel > rightWeight) {
rightWeight = totel;
}
if(leftWeight + rightWeight > res) {
res = leftWeight + rightWeight;
}
}
}
return Math.max(leftWeight,rightWeight);
}