leetcode886.PossibleBipartition

转自:https://blog.csdn.net/QingyunAlgo/article/details/82106963
题目: 有N个人,编号从1到N。现在我们试图把他们分成两组。一个人可能不喜欢某些人,那么这个人和他不喜欢的人不能分到一组。输入一个数组dislikes,数组的第i项dislikes[i] = [a, b]表示编号为a的人不喜欢编号为b的人,因此他们不能分到同一组。请根据dislikes关系判断输入的N个人能否分到两个组里?
输入: N个人,一个二维数组 dislikes
输出:true or false
别人思路: 要想解决这个问题,首先我们要发现这个题目是关于图的问题。每个人是图中的一个节点。如果一个人a不喜欢另一个人b,那么a与b之间有一条边相连。在这个题目中a不喜欢b意味着a、b不能分到同一组。不管b是否不喜欢a,只要a不喜欢b他们就不能放在同一组里。因此这个图是无向图。如果看成有向图,只要从a到b有一条边,那么从b到a也有一条边。

如果这些人能够分成两组,我们可以想象这些人在图中对应的节点能够用两种颜色标记。分到第一组的人用颜色c1标记,另一组的人用颜色c2标记。接着我们考虑怎么给图中每个节点标记颜色。

最开始的时候每个节点都没有标记颜色。我们逐个扫描图中的节点,如果发现一个节点p没有被标记过颜色,那么给他标记颜色c1。接着我们看这个节点p都有哪些节点和它相邻,如果相邻的节点q之前没有标记过颜色,我们给它们标记成c2。这是因为p和q相邻,表示他们之间相互不喜欢,不能分在同一组,因此不能用相同的颜色标记。如果节点q之前已经被标记过颜色了,那么看之前标记的是什么颜色。如果之前标记的是c2,那么没有必要再重复标记了。如果之前标记的颜色是c1,那么出现冲突了,一个人不能分到两个组里,因此我们不能按照这个分组规则把所有人分成两组。

接下来我们再从节点q出发去,把和它相邻的节点标记颜色c1,再以此类推。这就是一个深度优先搜索的过程。下面是基于图的深度优先搜索的参考代码:

class Solution {
    public boolean possibleBipartition(int N, int[][] dislikes) {
        HashMap<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>() ;
        int key ;
        for(int i=1;i<=N;i++){
            List<Integer> list = new ArrayList<Integer>() ;
            map.put(i, list) ;
        }
        for(int i=0;i<dislikes.length;i++){
            key = dislikes[i][0] ;
            map.get(key).add(dislikes[i][1]) ;
            if(!map.get(dislikes[i][1]).contains(key)){
            map.get(dislikes[i][1]).add(key) ;
            }
        }
        int colors[] = new int[N+1] ;
        Arrays.fill(colors, -1);
        for(int i=1;i<=N;i++){
            if(colors[i] == -1 && !dfs(map, colors, i, 0)){
                return false ;
            }
        }
        return true ;
    }
    public boolean dfs(Map<Integer, List<Integer>> map, int colors[], int index, int value){
        if(colors[index] != -1){
            return colors[index] == value ;
        }
        colors[index] = value ;
        int len = map.get(index).size() ;
        for(int i=0;i<len;i++){
            if(!dfs(map, colors, map.get(index).get(i), 1-value)){
                return false ;
            }
        }
        return true ;
    }
}

猜你喜欢

转载自blog.csdn.net/u011732358/article/details/83472153