『力扣题解』并查集

86 阅读1分钟

886. 可能的二分法

本题比较巧妙,只是要求分成两组,对于每一个成员i,他讨厌的人都在另一个集合中。因为只有两个集合,不妨给每个点都设置“反向点”,如果x和y的反向点在一个集合内,说明x和y不能在一个集合内

当a讨厌b时,b应该在另一个集合,那么b + n就和a在一个集合中,采用merge操作,a + n就和b在一个集合中,同理。

就这样,对于每一个dislike,都可以merge两次,如果后续dislike的两个点在同一个集合,则返回false。

举个例子,[1, 2], [1, 3], [2, 3]:可知2、3都和1的反向点4在同一个集合中,这说明它们都不能和1在一个集合,然后[2, 3]来了,要求它们又不能在一个集合,显然不能满足。

function merge(fa, a, b) {
  const f1 = find(fa, a);
  const f2 = find(fa, b);
  fa[f2] = f1;
}

function find(fa, x) {
  return fa[x] === x ? x : (fa = find(fa, fa[x]));
}

var possibleBipartition = function (n, dislikes) {
  const fa = Array(2 * n + 1).fill(0);
  for (let i = 1; i <= 2 * n; i++) {
    fa[i] = i;
  }
  for (const [a, b] of dislikes) {
    if (find(fa, a) === find(fa, b)) {
      return false;
    }
    merge(fa, a, b + n);
    merge(fa, b, a + n);
  }
  console.log(fa);
  return true;
};