Given an undirected tree consisting of n
vertices numbered from 0 to n-1
, which has some apples in their vertices. You spend 1 second to walk over one edge of the tree. Return the minimum time in seconds you have to spend in order to collect all apples in the tree starting at vertex 0 and coming back to this vertex.
The edges of the undirected tree are given in the array edges
, where edges[i] = [fromi, toi]
means that exists an edge connecting the vertices fromi
and toi
. Additionally, there is a boolean array hasApple
, where hasApple[i] = true
means that vertex i
has an apple, otherwise, it does not have any apple.
Example 1:
Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,true,false,true,true,false] Output: 8 Explanation: The figure above represents the given tree where red vertices have an apple. One optimal path to collect all apples is shown by the green arrows.
思路:建立一个单向图,从叶子节点到根节点,然后从apple开始travel 到根,如果点visite过了,就不继续,只计算没有visited的node的step;visited.add(x)返回true or false,这个可以提速;
class Solution {
public int minTime(int n, int[][] edges, List<Boolean> hasApple) {
// build graph;
HashMap<Integer, Integer> graph = new HashMap<>();
for(int[] e: edges) {
graph.put(e[1], e[0]);
}
List<Integer> apples = new ArrayList<Integer>();
for(int i = 0; i < n; i++) {
if(hasApple.get(i) && i != 0) {
apples.add(i);
}
}
HashSet<Integer> visited = new HashSet<Integer>();
int step = 0;
for(Integer apple: apples) {
if(visited.add(apple)) {
step += backward(apple, graph, visited);
}
}
return step;
}
private int backward(int x, HashMap<Integer, Integer> graph, HashSet<Integer> visited) {
int step = 0;
while(graph.get(x) != 0 && visited.add(graph.get(x))) {
x = graph.get(x);
step = step + 2;
}
// 注意从倒数第一步到顶点,也算是一步,也要+2;
return step + 2;
}
}