zoukankan      html  css  js  c++  java
  • [LeetCode] 1443. Minimum Time to Collect All Apples in a Tree

    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.

    Example 2:

    Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], 
    hasApple = [false,false,true,false,false,true,false] Output: 6 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.

    Example 3:

    Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], 
    hasApple = [false,false,false,false,false,false,false] Output: 0

    Constraints:

    • 1 <= n <= 10^5
    • edges.length == n-1
    • edges[i].length == 2
    • 0 <= fromi, toi <= n-1
    • fromi < toi
    • hasApple.length == n

    收集树上所有苹果的最少时间。题意是给一个树和几个参数,其中N表示树的节点个数,edges代表每个节点之间的连接关系,hasApple是一个boolean数组,表示每个节点上是否有苹果,请你返回如果从节点0开始找,需要花费多少时间找到所有苹果并返回节点0。

    discussion里面绝大部分的思路都是DFS,我的解法也不例外。我用到这么几个数据结构

    • list of list - 创建邻接表
    • boolean数组记录哪些node被遍历过了

    先创建邻接表,这里注意虽然题目中说了是tree但是其实是一个多叉树,所以还是当做一个graph在处理。然后因为你是从0开始遍历所以在做DFS前,先把0标记为visited。在DFS的时候,因为是多叉树所以要对每个node的children list做for循环,看每一个孩子节点是否有苹果。count代表需要走几步,所以如果某个节点的孩子节点传上来的count > 0的话(表示下面有苹果),或者这个节点本身是有苹果的(hasApple.get(v) == true),那么就意味着一定需要走过去拿苹果,所以count += 2。走两步是因为一来一回。

    时间O(n)

    空间O(n)

    Java实现 - 2020年10月更新

     1 class Solution {
     2     public int minTime(int n, int[][] edges, List<Boolean> hasApple) {
     3         List<List<Integer>> adj = new ArrayList<>();
     4         for (int i = 0; i < n; i++) {
     5             adj.add(i, new ArrayList<>());
     6         }
     7         for (int[] e : edges) {
     8             adj.get(e[0]).add(e[1]);
     9             adj.get(e[1]).add(e[0]);
    10         }
    11         boolean[] visited = new boolean[n];
    12         visited[0] = true;
    13         return dfs(adj, hasApple, 0, visited);
    14     }
    15 
    16     private int dfs(List<List<Integer>> adj, List<Boolean> hasApple, int v, boolean[] visited) {
    17         if (adj.get(v) == null) {
    18             return 0;
    19         }
    20         int count = 0;
    21         List<Integer> children = adj.get(v);
    22         for (int child : children) {
    23             if (!visited[child]) {
    24                 visited[child] = true;
    25                 count += dfs(adj, hasApple, child, visited);
    26             }
    27         }
    28         if ((count > 0 || hasApple.get(v)) && v != 0) {
    29             count += 2;
    30         }
    31         return count;
    32     }
    33 }

    LeetCode 题目总结

  • 相关阅读:
    Java 集合系列06之 Vector详细介绍(源码解析)和使用示例
    Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
    Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理、解决办法)
    linked-list-cycle-ii-LeetCode
    reorder-list-LeetCode
    sum-root-to-leaf-numbers-LeetCode
    binary-tree-maximum-path-sum-LeetCode
    机器人的运动范围-剑指Offer
    矩阵中的路径-剑指Offer
    滑动窗口的最大值-剑指Offer
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12875690.html
Copyright © 2011-2022 走看看