给定一组 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
本质上就是看相邻的两个点是不是能够染成不同的颜色。
package com.loo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class PossibleDichotomy {
private static ArrayList<Integer>[] graph = null;
private static Map<Integer , Integer> map = null;
public static void main(String[] args) {
int[][] dislikes = {{1,2},{1,3},{2,4}};
int N = 4;
int[][] dislikes2 = {{1,2},{1,3},{2,3}};
int N2 = 3;
System.out.println(possibleDichotomy(dislikes2 , N2));
}
public static boolean possibleDichotomy(int[][] dislike , int N) {
graph = new ArrayList[N + 1];
for (int i=1;i<=N;i++) {
graph[i] = new ArrayList<Integer>();
}
for (int[] edge : dislike) {
graph[edge[0]].add(edge[1]);
graph[edge[1]].add(edge[0]);
}
map = new HashMap();
for (int i=1;i<=N;i++) {
if (!map.containsKey(i) && !dfs(i , 0)) {
return false;
}
}
return true;
}
public static boolean dfs(int node , int v) {
if (map.containsKey(node)) {
return map.get(node) == v;
}
map.put(node , v);
for (int in : graph[node]) {
if (!dfs(in , v^1)) {
return false;
}
}
return true;
}
}