Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 1443. Minimum Time to Collect All Apples in a Tree

Woodyiiiiiii opened this issue · comments

这道题并不难,我花了17分钟就AC了。但因为觉得有些注意的点,就打算记录下来。

Tips:

  1. 这是一颗多叉树,边和节点都确定了,并不是图(说明每个节点只有一个父节点,跟图不一样)这是竞赛中学到的
  2. 这种问题先记录边,用Map存储
  3. 如何求出最短路径,实际上树和图的问题基础上都是用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;
    }
}