Leetcode 1443. Minimum Time to Collect All Apples in a Tree
Woodyiiiiiii opened this issue · comments
这道题并不难,我花了17分钟就AC了。但因为觉得有些注意的点,就打算记录下来。
Tips:
- 这是一颗多叉树,边和节点都确定了,并不是图(说明每个节点只有一个父节点,跟图不一样)
这是竞赛中学到的 - 这种问题先记录边,用Map存储
- 如何求出最短路径,实际上树和图的问题基础上都是用DFS来解决的。这里很容易想到要用到后序遍历,所以稍微改变下前序遍历的写法,先DFS得到子节点值,再返回给上层,顺序颠倒下,这是先序遍历和后序遍历根本的不同,不需要用一个专门的Map记录父节点
class Solution {
public int minTime(int n, int[][] edges, List<Boolean> hasApple) {
// convert hasApple to map
Map<Integer, Boolean> appleMap = new HashMap<>();
for (int i = 0; i < hasApple.size(); i++) {
appleMap.put(i, hasApple.get(i));
}
// convert edges to map
Map<Integer, List<Integer>> edgeMap = new HashMap<>();
for (int[] edge : edges) {
int from = edge[0];
int to = edge[1];
List<Integer> list = edgeMap.getOrDefault(from, new ArrayList<>());
list.add(to);
edgeMap.put(from, list);
List<Integer> list2 = edgeMap.getOrDefault(to, new ArrayList<>());
list2.add(from);
edgeMap.put(to, list2);
}
// post order traversal
return postorder(edgeMap, appleMap, -1, 0);
}
private int postorder(Map<Integer, List<Integer>> edgeMap, Map<Integer, Boolean> appleMap, int pre, int cur) {
if (edgeMap.get(cur).size() == 1 && edgeMap.get(cur).get(0) == pre) {
return appleMap.get(cur) ? 2 : 0;
}
int sum = 0;
for (int next : edgeMap.get(cur)) {
if (next == pre) {
continue;
}
int time = postorder(edgeMap, appleMap, cur, next);
if (time > 0) {
sum += time;
}
}
if (cur != 0 && (sum > 0 || appleMap.get(cur))) {
sum += 2;
}
return sum;
}
}