Java subset + check valid subtree + DFS
Explanation from perspective of \u83DC\u9E1F like me:\n1. Get subset of all possibilities of 2 ^ n.  Then the number from each subset could potentially becomes 
Explanation from perspective of \u83DC\u9E1F like me:\n1. Get subset of all possibilities of 2 ^ n.  Then the number from each subset could potentially becomes a subtree. Say we choose subset [1, 2] from [1,2,3,4].\n\nActually I don\'t know if this is the standard approach for similar subtree questions? During contest I\'ve never thought in this way. I directly start searching the graph but of course not work. \n\nbtw, one advanced approach for getting subsets is to apply bitmask magic. And I don\'t know if traditional backtracking would result in TLE or not.\n\n2. However, NOT all subset can really form a subtree. The criterion for being valid subtree: \nThe number of nodes in subtree == number of edges in subtree + 1.\nAnd also subtree.size() != 1\nSince edges.length is quite short, just traverse the edges and easiy figure out number of edges.\n\n3. Once you have a valid subtree, then this question deteriorates into tree diameter question. Then can solve by two BFS or DFS as we see in "1245 Tree Diameter"\n\n\n```\nclass Solution {\n    int maxPath = 0;\n    public int[] countSubgraphsForEachDiameter(int n, int[][] edges) {\n        int[] res = new int[n - 1];\n        \n        // Preparation to contruct graph\n        List<Integer>[] adjs = new List[n + 1];\n        for (int i = 1; i <= n; i++) {\n            adjs[i] = new ArrayList<>();\n        }\n        \n        for (int[] edge : edges) {\n            adjs[edge[0]].add(edge[1]);\n            adjs[edge[1]].add(edge[0]);\n        }\n     \n        // Get subset\n        int total = 1 << n; // 2 ^ n subsets\n        for (int i = 0; i < total; i++) {\n            Set<Integer> subset = new HashSet<>();\n            for (int j = 0; j < n; j++) {\n                if ((i & (1 << j)) > 0) { // bitmask to find subsets\n                    subset.add(j + 1);\n                }\n            }\n            \n            // Check if subset is valid tree.\n            // node # should be edge count + 1;\n            int count = 0; // edge count\n            for (int[] edge : edges) {\n                if (subset.contains(edge[0]) &&\n                    subset.contains(edge[1])) {\n                    count++;\n                }\n            }\n            if (subset.size() == 1 || subset.size() != count + 1) continue;\n            \n            int start = 0;\n            for (int num : subset) {\n                start = num;\n                break;\n            }\n            \n            maxPath = 0;\n\t\t\t// dfs to find max path for each subtree\n            dfs(start, -1, subset, adjs);\n            res[maxPath - 1]++;\n        }\n\n        return res;\n    }\n    \n    private int dfs(int root, int parent, Set<Integer> subtree, List<Integer>[] adjs) {\n        int firstMax = 0, secondMax = 0;\n        for (int child : adjs[root]) {\n            if (child == parent || !subtree.contains(child)) continue;\n            int childLen = dfs(child, root, subtree, adjs) + 1;\n            if (childLen > firstMax) {\n                secondMax = firstMax;\n                firstMax = childLen;\n            } else if (childLen > secondMax) {\n                secondMax = childLen;\n            }\n        }\n        maxPath = Math.max(maxPath, firstMax + secondMax);\n        return firstMax;\n    }\n}\n```
[]