leetcode t886 可能的二分法

t886 可能的二分法

1. 题目

给定一组 n 人(编号为 1, 2, ..., n), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。

给定整数 n 和数组 dislikes ,其中 dislikes[i] = [ai, bi] ,表示不允许将编号为 ai 和 bi的人归入同一组。当可以用这种方法将所有人分进两组时,返回 true;否则返回 false

链接

2. 分析

我们可以[ai,bi]看作是图的一条边。这样一来dislikes数组就变成一个边的集合,里面的点都是属于[1 , n]范围中。

如:

dislikes = [ [ 1,2 ], [ 2,3 ], [ 1,3 ] ]

可以转换成如下的图

转换成图了之后我们就很容易想到答案的处理方式了。

我们接下来,手腕一个用例来确定求解过程。

用例一:
n = 4, dislikes = [[1,2],[1,3],[2,4]]

经过上图,我们可以发现,当两个点相连的时候我们不能把他们涂成同一个颜色,一次我们可以从起点出发,逐层遍历,按层数的奇偶性来确定每一层的颜色。

值得注意的是,每一个点都只能有一种颜色。也就是说,像是第一个图中,如果我们选择节点1出发,那么将它涂成红色,按照我们的规则,

(1)节点2、3就应该都是绿色。

(2)但是节点3和节点2之间存在一条边,根据相邻的点颜色不能相同可知,节点2和节点3的颜色应该不同。

因此,这个图不能被分成一个可能的二分图。

而从上述的思路中,我们提到了逐层遍历,很显然,可以使用BFS实现该算法。

至于判断一个节点是否存在多个颜色,我们可以使用哈希表(或者长度为n的数组)来存放当前元素的颜色,注意有三种状态:没有颜色,红色,绿色。

如果一个节点没有颜色,那么无论他是被红色节点遍历到还是被绿色节点遍历到,我们我们直接把颜色取反即可。

而对于有颜色的节点,我们只需要判断现在节点的颜色,是否与我们根据推断出来的节点颜色相同即可。如果相同,那么继续遍历,如果不同,那么说明不存在,return false;

3. 代码


class Solution {
    Map<Integer,Integer> map;//index-color
    List<Integer>[] lists;
    public boolean possibleBipartition(int n, int[][] dl) {
        map = new HashMap<>();
        lists = new List[n+1];
        for(int i = 1;i<=n;i++) lists[i]=new ArrayList<>();
        for(int i = 0;i<dl.length;i++){
            int[] e = dl[i];
            lists[e[0]].add(e[1]);
            lists[e[1]].add(e[0]);
        }
        for(int i = 1;i<=n;i++){
            if(map.get(i)==null){
                if(bfs(i)){
                    continue;
                }
                else{
                    return false;
                }
            }
            else{
                continue;
            }
        }
        return true;
    }
    public boolean bfs(int index){
        Deque<Integer>[] qs=new Deque[2];
        qs[0] = new ArrayDeque<Integer>();
        qs[1] = new ArrayDeque<Integer>();
        Deque<Integer> cur = qs[0];
        Deque<Integer> next = qs[1];
        map.put(index,1);
        cur.offer(index);
        while(cur.size()!=0){
            while(cur.size()!=0){
                int idx = cur.poll();
                for(int i = 0;i<lists[idx].size();i++){
                    if(map.get(lists[idx].get(i))==null){
                        map.put(lists[idx].get(i),3-map.get(idx));
                        next.offer(lists[idx].get(i));
                    }
                    else if(map.get(lists[idx].get(i))==map.get(idx)){
                        return false;
                    }
                }
            }
            cur = (cur==qs[0])?qs[1]:qs[0];
            next = (next==qs[0])?qs[1]:qs[0];
        }
        return true;
    }
}
posted @ 2022-10-17 20:15  QViVi  阅读(29)  评论(0)    收藏  举报