Possible Bipartition

medium graph union find dfs bfs

Problem

Given n people (1..n) and a list of pairs that dislike each other, decide whether everyone can be split into two groups with no dislike edge inside a group.

Inputn=4, dislikes=[[1,2],[1,3],[2,4]]
Outputtrue
Group A = {1,4}, Group B = {2,3}.

from collections import defaultdict, deque
def possibleBipartition(n, dislikes):
    g = defaultdict(list)
    for a, b in dislikes:
        g[a].append(b); g[b].append(a)
    color = {}
    for s in range(1, n + 1):
        if s in color: continue
        color[s] = 0
        q = deque([s])
        while q:
            u = q.popleft()
            for v in g[u]:
                if v not in color:
                    color[v] = 1 - color[u]
                    q.append(v)
                elif color[v] == color[u]:
                    return False
    return True
function possibleBipartition(n, dislikes) {
  const g = Array.from({ length: n + 1 }, () => []);
  for (const [a, b] of dislikes) { g[a].push(b); g[b].push(a); }
  const color = new Array(n + 1).fill(-1);
  for (let s = 1; s <= n; s++) {
    if (color[s] !== -1) continue;
    color[s] = 0;
    const q = [s]; let head = 0;
    while (head < q.length) {
      const u = q[head++];
      for (const v of g[u]) {
        if (color[v] === -1) { color[v] = 1 - color[u]; q.push(v); }
        else if (color[v] === color[u]) return false;
      }
    }
  }
  return true;
}
class Solution {
    public boolean possibleBipartition(int n, int[][] dislikes) {
        List<List<Integer>> g = new ArrayList<>();
        for (int i = 0; i <= n; i++) g.add(new ArrayList<>());
        for (int[] e : dislikes) { g.get(e[0]).add(e[1]); g.get(e[1]).add(e[0]); }
        int[] color = new int[n + 1];
        Arrays.fill(color, -1);
        for (int s = 1; s <= n; s++) {
            if (color[s] != -1) continue;
            color[s] = 0;
            Deque<Integer> q = new ArrayDeque<>(); q.offer(s);
            while (!q.isEmpty()) {
                int u = q.poll();
                for (int v : g.get(u)) {
                    if (color[v] == -1) { color[v] = 1 - color[u]; q.offer(v); }
                    else if (color[v] == color[u]) return false;
                }
            }
        }
        return true;
    }
}
bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
    vector<vector<int>> g(n + 1);
    for (auto& e : dislikes) { g[e[0]].push_back(e[1]); g[e[1]].push_back(e[0]); }
    vector<int> color(n + 1, -1);
    for (int s = 1; s <= n; s++) {
        if (color[s] != -1) continue;
        color[s] = 0;
        queue<int> q; q.push(s);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int v : g[u]) {
                if (color[v] == -1) { color[v] = 1 - color[u]; q.push(v); }
                else if (color[v] == color[u]) return false;
            }
        }
    }
    return true;
}
Time: O(n + E) Space: O(n + E)