持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
给定一组 n 人(编号为 1, 2, ..., n), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。
给定整数 n 和数组 dislikes ,其中 dislikes[i] = [ai, bi] ,表示不允许将编号为 ai 和 bi的人归入同一组。当可以用这种方法将所有人分进两组时,返回 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 <= 20000 <= dislikes.length <= 10^4dislikes[i].length == 21 <= dislikes[i][j] <= nai < bidislikes中每一组都 不同
思路
本题可以用深度优先搜索来解。假设第一组为A组,第二组为B组,依此遍历每个人,如果当前人没有被分组,就将其分到A组,那么这个不喜欢的人必定被分到B组,被分到B组的人,其不喜欢的人必定被分到A组,以此类推。如果分组过程中存在冲突,就表示不存在解,否则就说明可以分组,有正确解。
解题
/**
* @param {number} n
* @param {number[][]} dislikes
* @return {boolean}
*/
var possibleBipartition = function (n, dislikes) {
if (dislikes.length <= 1) return true;
const dfs = (curr, nowColor, color, g) => {
color[curr] = nowColor;
for (let i = 0; i < g[curr].length; i++) {
if (color[g[curr][i]] === 0) {
if (!dfs(g[curr][i], 3 ^ nowColor, color, g)) {
return false;
}
} else if (color[g[curr][i]] === nowColor) {
return false;
}
}
return true;
};
const color = new Array(n + 1).fill(0);
const g = new Array(n + 1).fill(0).map(() => []);
for (let i = 0; i < dislikes.length; i++) {
g[dislikes[i][0]].push(dislikes[i][1]);
g[dislikes[i][1]].push(dislikes[i][0]);
}
for (let i = 1; i <= n; i++) {
if (color[i] === 0 && !dfs(i, 1, color, g)) {
return false;
}
}
return true;
};