leetcode-可能的二分法

给定一组 N 人(编号为 1, 2, ..., N), 我们想把每个人分进任意大小的两组。

每个人都可能不喜欢其他人,那么他们不应该属于同一组。

形式上,如果 dislikes[i] = [a, b],表示不允许将编号为 a 和 b 的人归入同一组。

当可以用这种方法将所有人分进两组时,返回 true;否则返回 false。

示例 1:

输入:N = 4, dislikes = [[1,2],[1,3],[2,4]]
输出:true
解释:group1 [1,4], group2 [2,3]
示例 2:

输入:N = 3, dislikes = [[1,2],[1,3],[2,3]]
输出:false
示例 3:

输入:N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
输出:false
 

提示:

1 <= N <= 2000
0 <= dislikes.length <= 10000
dislikes[i].length == 2
1 <= dislikes[i][j] <= N
dislikes[i][0] < dislikes[i][1]
对于 dislikes[i] == dislikes[j] 不存在 i != j

扫描二维码关注公众号,回复: 13561699 查看本文章

题解

根据题意可知,一定是分为两组,问题在于怎么进行合理的分组。假设a和b互相讨厌,a和c互相讨厌,那么如果可以分组的话b和c一定是同一组。那个就将和a互相讨厌的人 找到,让他们属于一组(即给他们一个标签,可以通过染色或者通过并查集来标示)。以此类推,如果在对x的讨厌人群中出现了y,而x和y同属于a的讨厌人群,那么就不能分组。

首先对建图,来形成一个关系图,然后通过并查集将同被一个人讨厌的人群组成一个连通分量,然后遍历判断互为讨厌的人是否在同一个连通分量中,如果互为讨厌的人是否在同一个连通分量中,那么不能分组成功,否则可以分组成功

class Solution {
    int[] arr;
    ArrayList<Integer>[] graph;

    int find(int x) {
        while(x!=arr[x]) {
            x = arr[x];
        }
        return x;
    }
    public boolean possibleBipartition(int n, int[][] dislikes) {
        graph = new ArrayList[n+1];
        arr = new int[n+1];
        for(int i = 0;i<=n;i++) {
            arr[i] = i;
            graph[i] = new ArrayList();
        } 

        for(int[] eage: dislikes) {
            graph[eage[0]].add(eage[1]);
            graph[eage[1]].add(eage[0]);
        }

        for(int i = 1;i<=n;i++) {
            for(int j: graph[i]) {
                if(find(i) == find(j)) return false;
                arr[find(graph[i].get(0))] = find(j);
            }
        }

        return true;

    }
}

猜你喜欢

转载自blog.csdn.net/txgANG/article/details/120881160