Given a Graph with V vertices (Numbered from 0 to V-1) and E edges. Check whether the graph is bipartite or not.
A bipartite graph can be colored with two colors such that no two adjacent vertices share the same color. This means we can divide the graph’s vertices into two distinct sets where:
All edges connect vertices from one set to vertices in the other set.
No edges exist between vertices within the same set.
Examples:
Input: V = 3, edges[][] = [[0, 1], [1,2]]
Output: true Explanation: The given graph can be colored in two colors so, it is a bipartite graph.
[Naive Approach] Using Brute Force Two Coloring - O(2^V × (V + E)) Time and O(V + E) Space
The idea is to recursively assign one of the two colors to every vertex. Before assigning a color, check whether any adjacent vertex already has the same color. If no valid coloring is possible after trying both colors, the graph is not bipartite.
Working of Approach:
Create an adjacency list from the given edges.
Recursively assign either color 0 or 1 to every uncolored vertex.
Before assigning a color, ensure that none of its adjacent vertices has the same color.
If a color leads to a conflict, backtrack and try the other color.
If all vertices are colored successfully, return true; otherwise, return false.
C++
#include<iostream>#include<vector>usingnamespacestd;// Function to create adjacency list.vector<vector<int>>constructAdj(intV,vector<vector<int>>&edges){vector<vector<int>>adj(V);for(auto&e:edges){adj[e[0]].push_back(e[1]);adj[e[1]].push_back(e[0]);}returnadj;}// Function to check whether assigning the color is safe.boolisSafe(intnode,intclr,vector<int>&color,vector<vector<int>>&adj){// Check all adjacent vertices.for(intneigh:adj[node]){if(color[neigh]==clr)returnfalse;}returntrue;}// Backtracking function.boolsolve(intnode,intV,vector<int>&color,vector<vector<int>>&adj){// All vertices are colored.if(node==V)returntrue;// Skip already colored vertices.if(color[node]!=-1)returnsolve(node+1,V,color,adj);// Try both colors.for(intclr=0;clr<=1;clr++){if(isSafe(node,clr,color,adj)){// Assign color.color[node]=clr;// Recur for next vertex.if(solve(node+1,V,color,adj))returntrue;// Backtrack.color[node]=-1;}}returnfalse;}// Function to check if graph is bipartite.boolisBipartite(intV,vector<vector<int>>&edges){// Create adjacency list.vector<vector<int>>adj=constructAdj(V,edges);// -1 means vertex is uncolored.vector<int>color(V,-1);returnsolve(0,V,color,adj);}intmain(){intV=3;vector<vector<int>>edges={{0,1},{1,2}};if(isBipartite(V,edges))cout<<"true";elsecout<<"false";return0;}
Java
importjava.util.*;classGFG{// Function to create adjacency list.staticArrayList<ArrayList<Integer>>constructAdj(intV,int[][]edges){ArrayList<ArrayList<Integer>>adj=newArrayList<>();for(inti=0;i<V;i++)adj.add(newArrayList<>());for(int[]e:edges){adj.get(e[0]).add(e[1]);adj.get(e[1]).add(e[0]);}returnadj;}// Function to check whether assigning the color is// safe.staticbooleanisSafe(intnode,intclr,int[]color,ArrayList<ArrayList<Integer>>adj){// Check all adjacent vertices.for(intneigh:adj.get(node)){if(color[neigh]==clr)returnfalse;}returntrue;}// Backtracking function.staticbooleansolve(intnode,intV,int[]color,ArrayList<ArrayList<Integer>>adj){// All vertices are colored.if(node==V)returntrue;// Skip already colored vertices.if(color[node]!=-1)returnsolve(node+1,V,color,adj);// Try both colors.for(intclr=0;clr<=1;clr++){if(isSafe(node,clr,color,adj)){// Assign color.color[node]=clr;// Recur for next vertex.if(solve(node+1,V,color,adj))returntrue;// Backtrack.color[node]=-1;}}returnfalse;}// Function to check if graph is bipartite.staticbooleanisBipartite(intV,int[][]edges){// Create adjacency list.ArrayList<ArrayList<Integer>>adj=constructAdj(V,edges);// -1 means vertex is uncolored.int[]color=newint[V];Arrays.fill(color,-1);returnsolve(0,V,color,adj);}publicstaticvoidmain(String[]args){intV=3;int[][]edges={{0,1},{1,2}};System.out.println(isBipartite(V,edges));}}
usingSystem;usingSystem.Collections.Generic;classGFG{// Function to create adjacency list.staticList<int>[]ConstructAdj(intV,int[,]edges){List<int>[]adj=newList<int>[V];for(inti=0;i<V;i++)adj[i]=newList<int>();intm=edges.GetLength(0);for(inti=0;i<m;i++){intu=edges[i,0];intv=edges[i,1];adj[u].Add(v);adj[v].Add(u);}returnadj;}// Function to check whether assigning the color is// safe.staticboolIsSafe(intnode,intclr,int[]color,List<int>[]adj){// Check all adjacent vertices.foreach(intneighinadj[node]){if(color[neigh]==clr)returnfalse;}returntrue;}// Backtracking function.staticboolSolve(intnode,intV,int[]color,List<int>[]adj){// All vertices are colored.if(node==V)returntrue;// Skip already colored vertices.if(color[node]!=-1)returnSolve(node+1,V,color,adj);// Try both colors.for(intclr=0;clr<=1;clr++){if(IsSafe(node,clr,color,adj)){// Assign color.color[node]=clr;// Recur for next vertex.if(Solve(node+1,V,color,adj))returntrue;// Backtrack.color[node]=-1;}}returnfalse;}// Function to check if graph is bipartite.staticboolisBipartite(intV,int[,]edges){// Create adjacency list.List<int>[]adj=ConstructAdj(V,edges);// -1 means vertex is uncolored.int[]color=newint[V];Array.Fill(color,-1);returnSolve(0,V,color,adj);}staticvoidMain(){intV=3;int[,]edges={{0,1},{1,2}};Console.WriteLine(isBipartite(V,edges).ToString().ToLower());}}
Time Complexity: O(2^V × (V + E)), since each vertex can be assigned one of two colors, and every assignment checks adjacent vertices. Space Complexity: O(V + E), The adjacency list requires O(V + E) space, while the color array and recursion stack require O(V) space.
[Expected Approach - 1] Using BFS Graph Traversal with Two Coloring - O(V + E) Time and O(V + E) Space
The idea is to perform a BFS traversal and color each vertex with one of two colors. Every adjacent vertex is assigned the opposite color. If two adjacent vertices are found with the same color, the graph is not bipartite.
Working of Approach:
Create an adjacency list from the given edges.
Start BFS from every unvisited vertex to handle disconnected graphs.
Assign the starting vertex color 0 and color every neighbor with the opposite color.
If an already colored neighbor has the same color as the current vertex, return false.
If BFS finishes without any conflict, return true.
Let us understand with an example: Input: V = 3, edges[][] = [[0, 1], [1,2]]
Create the adjacency list as 0 -> {1}, 1 -> {0, 2}, and 2 -> {1}.
Initialize the color array as [-1, -1, -1] and start BFS from vertex 0.
Assign color 0 to vertex 0 and push it into the queue.
Visit vertex 1, assign it the opposite color 1, and push it into the queue.
Visit vertex 2 from vertex 1 and assign it color 0.
Every adjacent pair of vertices has different colors, so no conflict is found.
Therefore, the graph is bipartite, and the answer is true.
C++
#include<iostream>#include<queue>#include<vector>usingnamespacestd;vector<vector<int>>constructadj(intV,vector<vector<int>>&edges){vector<vector<int>>adj(V);for(autoit:edges){adj[it[0]].push_back(it[1]);adj[it[1]].push_back(it[0]);}returnadj;}// Function to check if the graph is bipartite or notboolisBipartite(intV,vector<vector<int>>&edges){// Vector to store colors of vertices.// Initialize all as -1 (uncolored)vector<int>color(V,-1);// create adjacency listvector<vector<int>>adj=constructadj(V,edges);// Queue for BFSqueue<int>q;// Iterate through all vertices to handle disconnected graphsfor(inti=0;i<V;i++){// If the vertex is uncolored, start BFS from itif(color[i]==-1){// Assign first color (0) to the starting vertexcolor[i]=0;q.push(i);// Perform BFSwhile(!q.empty()){intu=q.front();q.pop();// Traverse all adjacent verticesfor(auto&v:adj[u]){// If the adjacent vertex is uncolored,// assign alternate colorif(color[v]==-1){color[v]=1-color[u];q.push(v);}// If the adjacent vertex has the same color,// graph is not bipartiteelseif(color[v]==color[u]){returnfalse;}}}}}// If no conflicts in coloring, graph is bipartitereturntrue;}intmain(){intV=3;vector<vector<int>>edges={{0,1},{1,2}};if(isBipartite(V,edges))cout<<"true";elsecout<<"false";return0;}
Java
importjava.util.*;classGFG{staticArrayList<ArrayList<Integer>>constructAdj(intV,int[][]edges){ArrayList<ArrayList<Integer>>adj=newArrayList<>();for(inti=0;i<V;i++)adj.add(newArrayList<>());for(int[]it:edges){adj.get(it[0]).add(it[1]);adj.get(it[1]).add(it[0]);}returnadj;}// Function to check if the graph is bipartite or notstaticbooleanisBipartite(intV,int[][]edges){// Vector to store colors of vertices.// Initialize all as -1 (uncolored)int[]color=newint[V];Arrays.fill(color,-1);// Create adjacency listArrayList<ArrayList<Integer>>adj=constructAdj(V,edges);// Queue for BFSQueue<Integer>q=newLinkedList<>();// Iterate through all vertices to handle// disconnected graphsfor(inti=0;i<V;i++){// If the vertex is uncolored, start BFS from itif(color[i]==-1){// Assign first color (0) to the starting// vertexcolor[i]=0;q.offer(i);// Perform BFSwhile(!q.isEmpty()){intu=q.poll();// Traverse all adjacent verticesfor(intv:adj.get(u)){// If the adjacent vertex is// uncolored, assign alternate colorif(color[v]==-1){color[v]=1-color[u];q.offer(v);}// If the adjacent vertex has the// same color, graph is not// bipartiteelseif(color[v]==color[u]){returnfalse;}}}}}// If no conflicts in coloring, graph is bipartitereturntrue;}publicstaticvoidmain(String[]args){intV=3;int[][]edges={{0,1},{1,2}};if(isBipartite(V,edges))System.out.println("true");elseSystem.out.println("false");}}
Python
fromcollectionsimportdeque,defaultdictdefconstructadj(V,edges):adj=defaultdict(list)foru,vinedges:adj[u].append(v)adj[v].append(u)returnadj# Function to check if the graph is bipartite or notdefisBipartite(V,edges):# List to store colors of vertices.# Initialize all as -1 (uncolored)color=[-1]*V# create adjacency listadj=constructadj(V,edges)# Queue for BFSq=deque()# Iterate through all vertices to handle disconnected graphsforiinrange(V):# If the vertex is uncolored, start BFS from itifcolor[i]==-1:# Assign first color (0) to the starting vertexcolor[i]=0q.append(i)# Perform BFSwhileq:u=q.popleft()# Traverse all adjacent verticesforvinadj[u]:# If the adjacent vertex is uncolored,# assign alternate colorifcolor[v]==-1:color[v]=1-color[u]q.append(v)# If the adjacent vertex has the same color,# graph is not bipartiteelifcolor[v]==color[u]:returnFalse# If no conflicts in coloring, graph is bipartitereturnTrueif__name__=="__main__":V=3edges=[[0,1],[1,2]]ifisBipartite(V,edges):print("true")else:print("false")
C#
usingSystem;usingSystem.Collections.Generic;classGFG{staticList<int>[]ConstructAdj(intV,int[,]edges){List<int>[]adj=newList<int>[V];for(inti=0;i<V;i++)adj[i]=newList<int>();intm=edges.GetLength(0);for(inti=0;i<m;i++){adj[edges[i,0]].Add(edges[i,1]);adj[edges[i,1]].Add(edges[i,0]);}returnadj;}// Function to check if the graph is bipartite or notstaticboolisBipartite(intV,int[,]edges){// Vector to store colors of vertices.// Initialize all as -1 (uncolored)int[]color=newint[V];Array.Fill(color,-1);// Create adjacency listList<int>[]adj=ConstructAdj(V,edges);// Queue for BFSQueue<int>q=newQueue<int>();// Iterate through all vertices to handle// disconnected graphsfor(inti=0;i<V;i++){// If the vertex is uncolored, start BFS from itif(color[i]==-1){// Assign first color (0) to the starting// vertexcolor[i]=0;q.Enqueue(i);// Perform BFSwhile(q.Count>0){intu=q.Dequeue();// Traverse all adjacent verticesforeach(intvinadj[u]){// If the adjacent vertex is// uncolored, assign alternate colorif(color[v]==-1){color[v]=1-color[u];q.Enqueue(v);}// If the adjacent vertex has the// same color, graph is not// bipartiteelseif(color[v]==color[u]){returnfalse;}}}}}// If no conflicts in coloring, graph is bipartitereturntrue;}staticvoidMain(){intV=3;int[,]edges={{0,1},{1,2}};if(isBipartite(V,edges))Console.WriteLine("true");elseConsole.WriteLine("false");}}
JavaScript
functionconstructadj(V,edges){letadj=Array.from({length:V},()=>[]);for(letitofedges){adj[it[0]].push(it[1]);adj[it[1]].push(it[0]);}returnadj;}// Function to check if the graph is bipartite or notfunctionisBipartite(V,edges){// Array to store colors of vertices.// Initialize all as -1 (uncolored)letcolor=Array(V).fill(-1);// create adjacency listletadj=constructadj(V,edges);// Queue for BFSletq=[];// Iterate through all vertices to handle disconnected// graphsfor(leti=0;i<V;i++){// If the vertex is uncolored, start BFS from itif(color[i]===-1){// Assign first color (0) to the starting vertexcolor[i]=0;q.push(i);// Perform BFSwhile(q.length>0){letu=q.shift();// Traverse all adjacent verticesfor(letvofadj[u]){// If the adjacent vertex is uncolored,// assign alternate colorif(color[v]===-1){color[v]=1-color[u];q.push(v);}// If the adjacent vertex has the same// color, graph is not bipartiteelseif(color[v]===color[u]){returnfalse;}}}}}// If no conflicts in coloring, graph is bipartitereturntrue;}// Driver CodeletV=3;letedges=[[0,1],[1,2]];if(isBipartite(V,edges))console.log("true");elseconsole.log("false");
Output
true
Time Complexity: O(V + E), as every vertex is visited at most once and every edge is traversed at most twice during the BFS traversal. Space Complexity: O(V + E), The adjacency list requires O(V + E) space, while the color array and BFS queue require O(V) space.
[Expected Approach - 2] Using DFS Graph Traversal with Two Coloring - O(V + E) Time and O(V + E) Space
The idea is to perform a DFS traversal and color each vertex with one of two colors. During DFS, every adjacent vertex is assigned the opposite color. If two adjacent vertices receive the same color, the graph is not bipartite.
Working of Approach:
Create an adjacency list from the given edges.
Start DFS from every unvisited vertex.
Assign alternate colors while visiting adjacent vertices.
If an adjacent vertex already has the same color, return false.
If all components are colored successfully, return true.
C++
#include<iostream>#include<vector>usingnamespacestd;// Function to create adjacency list.vector<vector<int>>constructAdj(intV,vector<vector<int>>&edges){vector<vector<int>>adj(V);for(auto&e:edges){adj[e[0]].push_back(e[1]);adj[e[1]].push_back(e[0]);}returnadj;}// DFS function to color vertices.booldfs(intnode,intclr,vector<int>&color,vector<vector<int>>&adj){// Assign color to current vertex.color[node]=clr;// Visit all adjacent vertices.for(intneigh:adj[node]){// If the adjacent vertex is uncolored,// assign alternate color.if(color[neigh]==-1){if(!dfs(neigh,1-clr,color,adj))returnfalse;}// If the adjacent vertex has the same color,// graph is not bipartite.elseif(color[neigh]==clr){returnfalse;}}returntrue;}// Function to check if graph is bipartite.boolisBipartite(intV,vector<vector<int>>&edges){// Create adjacency list.vector<vector<int>>adj=constructAdj(V,edges);// -1 means vertex is uncolored.vector<int>color(V,-1);// Traverse every connected component.for(inti=0;i<V;i++){if(color[i]==-1){if(!dfs(i,0,color,adj))returnfalse;}}returntrue;}intmain(){intV=3;vector<vector<int>>edges={{0,1},{1,2}};if(isBipartite(V,edges))cout<<"true";elsecout<<"false";return0;}
Java
importjava.util.*;classGFG{// Function to create adjacency list.staticArrayList<ArrayList<Integer>>constructAdj(intV,int[][]edges){ArrayList<ArrayList<Integer>>adj=newArrayList<>();for(inti=0;i<V;i++)adj.add(newArrayList<>());for(int[]e:edges){adj.get(e[0]).add(e[1]);adj.get(e[1]).add(e[0]);}returnadj;}// DFS function to color vertices.staticbooleandfs(intnode,intclr,int[]color,ArrayList<ArrayList<Integer>>adj){// Assign color to current vertex.color[node]=clr;// Visit all adjacent vertices.for(intneigh:adj.get(node)){// If the adjacent vertex is uncolored,// assign alternate color.if(color[neigh]==-1){if(!dfs(neigh,1-clr,color,adj))returnfalse;}// If the adjacent vertex has the same color,// graph is not bipartite.elseif(color[neigh]==clr){returnfalse;}}returntrue;}// Function to check if graph is bipartite.staticbooleanisBipartite(intV,int[][]edges){// Create adjacency list.ArrayList<ArrayList<Integer>>adj=constructAdj(V,edges);// -1 means vertex is uncolored.int[]color=newint[V];Arrays.fill(color,-1);// Traverse every connected component.for(inti=0;i<V;i++){if(color[i]==-1){if(!dfs(i,0,color,adj))returnfalse;}}returntrue;}publicstaticvoidmain(String[]args){intV=3;int[][]edges={{0,1},{1,2}};if(isBipartite(V,edges))System.out.println("true");elseSystem.out.println("false");}}
Python
# Function to create adjacency list.defconstructAdj(V,edges):adj=[[]for_inrange(V)]foreinedges:adj[e[0]].append(e[1])adj[e[1]].append(e[0])returnadj# DFS function to color vertices.defdfs(node,clr,color,adj):# Assign color to current vertex.color[node]=clr# Visit all adjacent vertices.forneighinadj[node]:# If the adjacent vertex is uncolored, assign alternate color.ifcolor[neigh]==-1:ifnotdfs(neigh,1-clr,color,adj):returnFalse# If the adjacent vertex has the same color, graph is not bipartite.elifcolor[neigh]==clr:returnFalsereturnTrue# Function to check if graph is bipartite.defisBipartite(V,edges):# Create adjacency list.adj=constructAdj(V,edges)# -1 means vertex is uncolored.color=[-1]*V# Traverse every connected component.foriinrange(V):ifcolor[i]==-1:ifnotdfs(i,0,color,adj):returnFalsereturnTrueif__name__=='__main__':V=3edges=[[0,1],[1,2]]print('true'ifisBipartite(V,edges)else'false')
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Function to create adjacency list.staticList<int>[]ConstructAdj(intV,int[,]edges){List<int>[]adj=newList<int>[V];for(inti=0;i<V;i++)adj[i]=newList<int>();intm=edges.GetLength(0);for(inti=0;i<m;i++){adj[edges[i,0]].Add(edges[i,1]);adj[edges[i,1]].Add(edges[i,0]);}returnadj;}// DFS function to color vertices.staticboolDfs(intnode,intclr,int[]color,List<int>[]adj){// Assign color to current vertex.color[node]=clr;// Visit all adjacent vertices.foreach(intneighinadj[node]){// If the adjacent vertex is uncolored,// assign alternate color.if(color[neigh]==-1){if(!Dfs(neigh,1-clr,color,adj))returnfalse;}// If the adjacent vertex has the same color,// graph is not bipartite.elseif(color[neigh]==clr){returnfalse;}}returntrue;}// Function to check if graph is bipartite.staticboolisBipartite(intV,int[,]edges){// Create adjacency list.List<int>[]adj=ConstructAdj(V,edges);// -1 means vertex is uncolored.int[]color=newint[V];Array.Fill(color,-1);// Traverse every connected component.for(inti=0;i<V;i++){if(color[i]==-1){if(!Dfs(i,0,color,adj))returnfalse;}}returntrue;}staticvoidMain(){intV=3;int[,]edges={{0,1},{1,2}};if(isBipartite(V,edges))Console.WriteLine("true");elseConsole.WriteLine("false");}}
JavaScript
// Function to create adjacency list.functionconstructAdj(V,edges){letadj=Array.from({length:V},()=>[]);for(leteofedges){adj[e[0]].push(e[1]);adj[e[1]].push(e[0]);}returnadj;}// DFS function to color vertices.functiondfs(node,clr,color,adj){// Assign color to current vertex.color[node]=clr;// Visit all adjacent vertices.for(letneighofadj[node]){// If the adjacent vertex is uncolored, assign// alternate color.if(color[neigh]===-1){if(!dfs(neigh,1-clr,color,adj))returnfalse;}// If the adjacent vertex has the same color, graph// is not bipartite.elseif(color[neigh]===clr){returnfalse;}}returntrue;}// Function to check if graph is bipartite.functionisBipartite(V,edges){// Create adjacency list.letadj=constructAdj(V,edges);// -1 means vertex is uncolored.letcolor=Array(V).fill(-1);// Traverse every connected component.for(leti=0;i<V;i++){if(color[i]===-1){if(!dfs(i,0,color,adj))returnfalse;}}returntrue;}// Driver CodeletV=3;letedges=[[0,1],[1,2]];console.log(isBipartite(V,edges)?"true":"false");
Output
true
Time Complexity: O(V + E), Every vertex and every edge is visited at most once during the traversal. Space Complexity: O(V + E), The adjacency list requires O(V + E) space, while the color array and DFS recursion stack require O(V) space.