Description
We want to split a group of n people (labeled from 1 to n) into two groups of any size. Each person may dislike some other people, and they should not go into the same group.
Given the integer n and the array dislikes where dislikes[i] = [ai, bi] indicates that the person labeled ai does not like the person labeled bi, return true if it is possible to split everyone into two groups in this way.
Examples
Example 1:
Input: n = 4, dislikes = [[1,2],[1,3],[2,4]]
Output: true
Explanation: group1 [1,4] and group2 [2,3].
Example 2:
Input: n = 3, dislikes = [[1,2],[1,3],[2,3]]
Output: false
Example 3:
Input: n = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
Output: false
Constraints:
1 <= n <= 2000
0 <= dislikes.length <= 104
dislikes[i].length == 2
1 <= dislikes[i][j] <= n
ai < bi
All the pairs of dislikes are unique.
思路
当然他和785很接近,所以最开始的时候,就用BFS去判断能不能2色填充。
但是我在submission里面看到了另一种用并查集的方式,其实我不知道它的原理是什么,只是感官上觉得这种方式是合理的,就先记录一下,以后可以直接用
代码
BFS
class Solution {
public boolean possibleBipartition(int n, int[][] dislikes) {
List<Set<Integer>> neighbors = new ArrayList<>();
if (dislikes.length == 0)
return true;
for (int i = 0; i < n; i++)
neighbors.add(new HashSet<>());
for (int[] pairs: dislikes) {
neighbors.get(pairs[0] - 1).add(pairs[1] - 1);
neighbors.get(pairs[1] - 1).add(pairs[0] - 1);
}
int[] color = new int[n];
int[] visited = new int[n];
for (int i = 0; i < n ; i++) {
if (visited[i] == 1)
continue;
List<Integer> parent = new ArrayList<>();
parent.add(i);
int currColor = 1;
color[i] = 1;
while(parent.size() != 0) {
List<Integer> children = new ArrayList<>();
for (int start: parent) {
if (visited[start] == 1)
continue;
visited[start] = 1;
for (int end: neighbors.get(start)) {
if (color[end] == currColor)
return false;
if (color[end] == -currColor)
continue;
color[end] = -currColor;
children.add(end);
}
}
currColor = -currColor;
parent = children;
}
}
return true;
}
}
并查集
class Solution {
int[] parent;
public void union(int x, int y) {
int parentX = find(x);
int parentY = find(y);
if (parentX == parentY)
return;
parent[parentX] = parentY;
}
public int find(int x) {
if (x != parent[x])
parent[x] = find(parent[x]);
return parent[x];
}
public boolean possibleBipartition(int n, int[][] dislikes) {
parent = new int[2 * n];
for (int i = 0; i < n * 2; i++) {
parent[i] = i;
}
for (int[] dislike: dislikes) {
union(dislike[0] - 1 + n, dislike[1] - 1);
union(dislike[0] - 1, dislike[1] - 1 + n);
}
for (int i = 0; i < n; i++) {
if (find(i) == find(i + n))
return false;
}
return true;
}
}