1916. Count Ways to Build Rooms in an Ant Colony

Difficulty:
Related Topics:
Similar Questions:

    Problem

    You are an ant tasked with adding n new rooms numbered 0 to n-1 to your colony. You are given the expansion plan as a 0-indexed integer array of length n, prevRoom, where prevRoom[i] indicates that you must build room prevRoom[i] before building room i, and these two rooms must be connected directly. Room 0 is already built, so prevRoom[0] = -1. The expansion plan is given such that once all the rooms are built, every room will be reachable from room 0.

    You can only build one room at a time, and you can travel freely between rooms you have already built only if they are connected. You can choose to build any room as long as its previous room is already built.

    Return **the *number of different orders* you can build all the rooms in**. Since the answer may be large, return it *modulo* 10^9 + 7.

      Example 1:

    Input: prevRoom = [-1,0,1]
    Output: 1
    Explanation: There is only one way to build the additional rooms: 012
    

    Example 2:

    Input: prevRoom = [-1,0,0,1,2]
    Output: 6
    Explanation:
    The 6 ways are:
    01324
    02413
    01234
    01243
    02134
    02143
    

      Constraints:

    Solution

    class Solution {
        int mod = (int)1e9 + 7;
        Map<Integer, List<Integer>> edges = new HashMap<>();
        int[] fac, inv;
    
        public int waysToBuildRooms(int[] prevRoom) {
            int n = prevRoom.length;
    
            this.fac = new int[n];//fac[i]=i!
            this.inv = new int[n];//inv[i]=i!^(-1)
            fac[0] = inv[0] = 1;
            for (int i = 1; i < n; i++) {
                fac[i] = (int)((long)fac[i - 1] * i % mod);
                inv[i] = quickmul(fac[i], mod - 2);// (fac[i]^(-1))%mod = (fac[i]^(mod-2))%mod
            }
    
            for (int i = 1; i < n; i++) {
                if (edges.containsKey(prevRoom[i]) == false)
                    edges.put(prevRoom[i], new ArrayList<Integer>());
                edges.get(prevRoom[i]).add(i);
            }
    
            return dfs(0)[1];      
        }
    
        public int[] dfs(int node) {
            if (edges.containsKey(node) == false)
                return new int[]{1, 1};
            int count = 1, arr = 1;
            for (int v : edges.get(node)) {
                int[] ret = dfs(v);
                count += ret[0];
                arr = (int)((long)arr * ret[1] % mod * inv[ret[0]] % mod);
            }
            arr = (int)((long)arr * fac[count - 1] % mod);
            return new int[]{count, arr};
        }
    
        public int quickmul(int x, int y) {
            long ret = 1, cur = x;
            while (y > 0) {
                if ((y & 1) == 1)
                    ret = ret * cur % mod;
                cur = cur * cur % mod;
                y >>= 1;
            }
            return (int)ret;
        }
    }
    
    

    Explain:

    nope.

    Complexity: