Given an undirected graph, return true if and only if it is bipartite.
Recall that a graph is bipartite if we can split it’s set of nodes into two independent subsets A and B such that every edge in the graph has one node in A and another node in B.
The graph is given in the following form: graph[i] is a list of indexes j for which the edge between nodes i and j exists. Each node is an integer between 0 and graph.length - 1. There are no self edges or parallel edges: graph[i] does not contain i, and it doesn’t contain any element twice.
Example 1:
Input: [[1,3], [0,2], [1,3], [0,2]]
Output: true
Example 2:
Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
Output: false
解题思路
本题是判断一个无向图是否为二分图,我使用染色法进行相邻节点的判断,并采取BFS进行图的遍历
- 初始化保存颜色的数组 color(0表示白色,1表示黑色,-1表示未染色),建立BFS队列以及判断该节点是否被遍历过的状态数组 check
- 从任意节点开始进行遍历,将该节点添加到BFS队列,颜色设为1,check 状态为true(我选择了0号节点)
- 每次从BFS队列中取出一个新节点,若该节点的子节点未被访问过(染色),那么将其染成与当前节点相反的颜色,并将这个子节点添加到BFS队列的尾部,设置 check 状态为true;否则,检查该子节点的颜色与当前节点是否相同,若相同,说明图中出现了奇数边的环,那么这个图不是二分图,返回false,结束
- 由于测试样例中有无出度的节点,因此在BFS队列为空的时候要检查一下状态数组 check 中是否还有未遍历的节点;若有,将其添加到BFS队列,继续遍历
- 当所有节点已经访问完毕,没有出现颜色重复的节点,说明这个图是二分图,返回true
C++代码
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
vector<int> color(graph.size(), -1);
queue<int> bfs_queue;
vector<bool> check(graph.size(), false);
color[0] = 1;
bfs_queue.push(0);
check[0] = true;
while(!bfs_queue.empty()) {
int p = bfs_queue.front();
bfs_queue.pop();
for(int i = 0; i < graph[p].size(); i++){
if(color[graph[p][i]] == -1){
color[graph[p][i]] = color[p] == 1? 0 : 1;
bfs_queue.push(graph[p][i]);
check[graph[p][i]] = true;
}
if(color[graph[p][i]] == color[p])
return false;
}
if(bfs_queue.empty()) {
for(int i = 0; i < check.size(); i++) {
if(!check[i]) {
bfs_queue.push(i);
color[i] = 1;
check[i] = true;
break;
}
}
}
}
return true;
}
};