
Problem Statement
In the given problem, we are provided with an undirected graph formed by n
nodes, identifiable by indices from 0
to n-1
. This graph is represented using a 2D array graph
, where graph[u]
enumerates all nodes directly connected to node u
. Key characteristics of this graph include:
- No node links to itself (
graph[u]
excludesu
), which rules out any self-edges. - Each connection between nodes is unique, ensuring no repetitive or parallel edges.
- The graph's nature is undirected; implying an edge from
u
tov
mandates a reciprocal edge fromv
tou
. - It's possible for the graph to be disjoint, wherein certain node pairs remain unconnected.
The primary objective is to determine if this graph can be classified as bipartite. A graph is termed bipartite if its nodes can be divided into two distinct groups such that every edge bridges one node from each group. The resolution should be boolean true
if the graph is bipartite and false
otherwise.
Examples
Example 1
Input:
graph = [[1,2,3],[0,2],[0,1,3],[0,2]]
Output:
false
Explanation:
There is no way to partition the nodes into two independent sets such that every edge connects a node in one and a node in the other.
Example 2
Input:
graph = [[1,3],[0,2],[1,3],[0,2]]
Output:
true
Explanation:
We can partition the nodes into two sets: {0, 2} and {1, 3}.
Constraints
graph.length == n
1 <= n <= 100
0 <= graph[u].length < n
0 <= graph[u][i] <= n - 1
graph[u]
does not containu
.- All the values of
graph[u]
are unique. - If
graph[u]
containsv
, thengraph[v]
containsu
.
Approach and Intuition
The classification of a graph as bipartite rests on whether it can be colored using two colors without two adjacent nodes sharing the same color. To understand the solution, consider the following steps based on the provided examples:
- Initiate a coloring attempt by selecting an initial node and assigning it a color (say, color 1).
- Use BFS (Breadth First Search) or DFS (Depth First Search) to attempt coloring the graph. During this traversal:
- Color an unvisited adjacent node with the opposite color.
- If a node is already colored with the wrong color (same color as current node), then the coloring is invalid, and the graph isn't bipartite.
For Example 1:
- Given the adjacency list
[[1,2,3],[0,2],[0,1,3],[0,2]]
:- Starting from node
0
and coloring it, leads to an attempt to color nodes1, 2, 3
differently but fails as node2
would require two different colors simultaneously, based on its adjacency with both0
and1
.
- Starting from node
- The process early exits with a bipartite classification as
false
.
For Example 2:
- With the graph
[[1,3],[0,2],[1,3],[0,2]]
:- A valid bipartite coloring can be established (
0
and2
with one color,1
and3
with the other), fulfilling the criteria for all connecting edges.
- A valid bipartite coloring can be established (
- The approach confirms the graph is bipartite with a return value of
true
.
Enhancing this basic understanding with further checks like disconnected components and ensuring all component-specific colorings align with bipartite requirements will frame the complete solution.
Solutions
- C++
- Java
class Solution {
public:
bool canPartition(vector<vector<int>>& adjacencyList) {
int vertexCount = adjacencyList.size();
vector<int> colors(vertexCount, -1);
for (int vertex = 0; vertex < vertexCount; ++vertex) {
if (colors[vertex] == -1) {
stack<int> nodes;
nodes.push(vertex);
colors[vertex] = 0;
while (!nodes.empty()) {
int current = nodes.top();
nodes.pop();
for (int neighbor : adjacencyList[current]) {
if (colors[neighbor] == -1) {
nodes.push(neighbor);
colors[neighbor] = colors[current] ^ 1;
} else if (colors[neighbor] == colors[current]) {
return false;
}
}
}
}
}
return true;
}
};
To determine if a graph is bipartite using C++, the provided C++ code defines a solution by implementing a depth-first search (DFS) using a stack. The approach leverages an adjacency list representation of the graph.
- Initialize a
colors
vector with a size equal to the number of vertices in the graph and set all values to -1, representing unvisited nodes. - Iterate over each vertex. If it has not been visited (
colors[vertex] == -1
), start a DFS from this vertex. - For each vertex, use a stack to keep track of vertices to process. Assign the initial color
0
to the starting vertex. - Continue processing by popping the top vertex from the stack and examining its neighbors:
- If the neighbor hasn’t been colored, push it onto the stack and assign it the opposite color to its current node using XOR operation (
colors[neighbor] = colors[current] ^ 1
). - If a neighbor already has the same color as the current node, the graph is not bipartite, and the function returns
false
.
- If the neighbor hasn’t been colored, push it onto the stack and assign it the opposite color to its current node using XOR operation (
- If all vertices are processed without finding conflicting colors, the function returns
true
, indicating that the graph is bipartite.
This method efficiently checks bipartiteness by attempting to color the graph using two colors in a way where no two adjacent vertices share the same color.
class Solution {
public boolean checkBipartite(int[][] adjacencyList) {
int vertices = adjacencyList.length;
int[] colors = new int[vertices];
Arrays.fill(colors, -1);
for (int i = 0; i < vertices; ++i) {
if (colors[i] == -1) {
Stack<Integer> dfsStack = new Stack();
dfsStack.push(i);
colors[i] = 0;
while (!dfsStack.empty()) {
Integer current = dfsStack.pop();
for (int neighbor: adjacencyList[current]) {
if (colors[neighbor] == -1) {
dfsStack.push(neighbor);
colors[neighbor] = colors[current] ^ 1;
} else if (colors[neighbor] == colors[current]) {
return false;
}
}
}
}
}
return true;
}
}
Determine if a graph can be divided into two distinct sets with no two adjacent vertices in the same set using the provided Java method checkBipartite
.
This method takes a graph represented as an adjacency list and uses depth-first search (DFS) along with a coloring mechanism to check if the graph is bipartite:
Initialize an array,
colors
, to keep track of the color assigned to each vertex, using-1
to indicate an uncolored vertex.Use a loop to process each vertex. If a vertex is uncolored, start a DFS from that vertex:
- Use a stack to facilitate the DFS traversal. Push the initial vertex onto the stack and assign it a color (0).
- Continue by popping the stack and checking the adjacency list of the current vertex:
- If an adjacent vertex is uncolored, push it onto the stack and assign a color opposite to the current vertex (
0
becomes1
, and vice versa using XOR operation). - If an adjacent vertex has the same color as the current vertex, it violates the bipartite conditions. Hence, return
false
.
- If an adjacent vertex is uncolored, push it onto the stack and assign a color opposite to the current vertex (
If all vertices are processed without conflicts, return
true
, confirming that the graph is bipartite.
This algorithm effectively checks the bipartiteness of the graph by trying to two-color the graph such that no two adjacent vertices share the same color, returning true
if possible and false
otherwise. The use of DFS ensures that all vertices and their connections are checked, even for non-connected graphs.
No comments yet.