Bipartite graphs are graphs where the edges are only between the corresponding vertices of 2 distinct sets. A graph with no vertices is Bipartite, and a graph with more than one connected component can be Bipartite.
Detect whether a given graph is Bipartite in O(n) time and using max O(m+n) space where m is the number of edges and the number of vertices is n.
func isBipartite(_ edges: [(Int, Int)], _ n: Int) -> Bool {
var adjList: [[Int]] = Array(repeating: [], count: n)
for (src, dst) in edges {
adjList[src].append(dst)
adjList[dst].append(src)
}
var visited = Array(repeating: false, count: n)
var color = Array(repeating: -1, count: n)
func dfs(_ start: Int) -> Bool { ... }
for i in 0 ..< n {
if !visited[i] {
color[i] = 0
if !dfs(i) {
return false
}
}
}
return true
}
func dfs(_ start: Int) -> Bool {
visited[start] = true
for neighbour in adjList[start] {
if !visited[neighbour] {
color[neighbour] = 1 - color[start]
if !dfs(neighbour) {
return false
}
} else if color[neighbour] == color[start] {
return false
}
}
return true
}
We can replace the DFS function above with a modified BFS traversal.
func bfs(_ start: Int) -> Bool {
visited[start] = true
color[start] = 0
var queue = [start]
while !queue.isEmpty {
let curr = queue.removeFirst()
for neighbour in adjList[curr] {
if !visited[neighbour] {
visited[neighbour] = true
color[neighbour] = 1 - color[curr]
queue.append(neighbour)
} else if color[neighbour] == color[curr] {
return false
}
}
}
return true
}
We can solve the Bipartite graph detection problem using modified graph traversal w/ cycle detection. Cycle detection is a useful technique for many graphs questions.