Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leetcode 2581. Count Number of Possible Root Nodes #221

Open
Woodyiiiiiii opened this issue Mar 7, 2023 · 0 comments
Open

Leetcode 2581. Count Number of Possible Root Nodes #221

Woodyiiiiiii opened this issue Mar 7, 2023 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

这是一道re-rooting类型的树的题目。类似有:

re-rooting树题目大概是一个不确定根节点的多叉树,从所有可能的根节点为基础出题。

解法说到底就是两遍DFS。第一遍DFS类似预先处理,一般以0为根节点,然后找到0为根节点时的特殊解,记录缓存。然后观察从0逐步向子节点扩散,以这些字节点为根节点时,跟第一次DFS预先得到的对比,找到规律,从而优化时间复杂度。

class Solution {
    int ans = 0;

    public int rootCount(int[][] edges, int[][] guesses, int k) {
        int n = edges.length + 1;
        // convert edges to map
        Map<Integer, Set<Integer>> map = new HashMap<>();
        for (int[] edge : edges) {
            int u = edge[0], v = edge[1];
            map.putIfAbsent(u, new HashSet<>());
            map.putIfAbsent(v, new HashSet<>());
            map.get(u).add(v);
            map.get(v).add(u);
        }
        // convert guesses to map
        Map<Integer, Set<Integer>> guessMap = new HashMap<>();
        for (int[] g : guesses) {
            int u = g[0], v = g[1];
            guessMap.putIfAbsent(u, new HashSet<>());
            guessMap.get(u).add(v);
        }
        // start from 0
        int[] parent = new int[n];
        Arrays.fill(parent, -1);
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(0);
        parent[0] = 0;
        while (!queue.isEmpty()) {
            int u = queue.poll();
            for (int v : map.get(u)) {
                if (parent[v] != -1) continue;
                parent[v] = u;
                queue.offer(v);
            }
        }
        // check if guess is correct when root is 0
        int cnt = 0;
        for (int[] g : guesses) {
            int u = g[0], v = g[1];
            if (parent[v] == u) cnt++;
        }
        if (cnt >= k) ans++;

        // re-rooting/dfs
        for (int c : map.get(0)) {
            dfs(c, 0, map, cnt, k, guessMap);
        }

        return ans;
    }

    private void dfs(int cur, int p, Map<Integer, Set<Integer>> map, int cnt, int k, Map<Integer, Set<Integer>> guessMap) {
        if (guessMap.containsKey(cur) && guessMap.get(cur).contains(p)) cnt++;
        if (guessMap.containsKey(p) && guessMap.get(p).contains(cur)) cnt--;
        if (cnt >= k) ans++;
        if (!map.containsKey(cur)) return;
        for (int c : map.get(cur)) {
            if (c == p) continue;
            dfs(c, cur, map, cnt, k, guessMap);
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant