Leetcode 785. Is Graph Bipartite?
题目
解法: BFS或DFS+染色
对于二分图的判断是用经典的染色法。 染色的方式是,看能否用两种颜色将所有节点涂上颜色,并且保证相邻节点都是不一样的颜色。如果可以做到,那么说明图是可以二分的。
这道题目用BFS或者DFS都是可以的,换句话说用队列或者堆栈都可以。如果是BFS,那么在当前节点涂完色时候,你会把他相邻的节点都涂成另一种颜色。如果是DFS的话,当前节点涂完之后,你会把最近的相邻节点涂成另一种颜色,并且沿着这条边深入下去。如果在涂色过程中,发现有两个相邻节点的颜色是一样的话,那就证明图是不可二分的。
python:
class Solution:
def isBipartite(self, graph: List[List[int]]) -> bool:
painted = {}
for node in range(len(graph)):
if node not in painted:
q = collections.deque()
q.append(node)
painted[node] = 1
while q:
curr = q.popleft();
for nei in graph[curr]:
if nei not in painted:
q.append(nei)
painted[nei] = painted[curr]^1
elif painted[nei] == painted[curr]:
return False
C++
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
vector<int> painted(graph.size(),0);
for (int node=0;node<graph.size();node++){
if (!painted[node]){
stack<int> s;
s.push(node);
painted[node] = 1;
while (!s.empty()){
int curr = s.top();
s.pop();
for (auto nei:graph[curr]){
if (painted[nei]==0){
s.push(nei);
painted[nei] = painted[curr]==1?2:1;
}else if(painted[nei] == painted[curr]) return false;
}
}
}
}
return true;
}
};
二刷BFS
上面是用bfs写的,这次用dfs写,不知道为何提交的时间快很多,理论上讲时间复杂度是完全一样的
class Solution:
def isBipartite(self, graph: List[List[int]]) -> bool:
def dfs(node):
res = True
for neigh in graph[node]:
if neigh in color_mapping:
if color_mapping[node] == color_mapping[neigh]:
return False
else:
color_mapping[neigh] = color_mapping[node] ^ 1
res = dfs(neigh) and res
return res
color_mapping = {}
for node in range(len(graph)):
if node in color_mapping:
continue
color_mapping[node] = 1
if not dfs(node):
return False
return True
c++版本bfs
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
int n = graph.size();
vector<int> node_colors(n,-2);
for(int node=0;node<n;node++){
if(node_colors[node] != -2) continue;
queue<pair<int,int>> q;
q.push(make_pair(node,1));
// int color = 1;
while(!q.empty()){
pair<int,int> top = q.front();
int curr = top.first;
int color = top.second;
// cout << curr << " " << color << endl;
q.pop();
node_colors[curr] = color;
for(auto& neigh : graph[curr]){
if(node_colors[neigh] == -2){
// node_colors[neigh] = color*-1;
q.push(make_pair(neigh,color*-1));
}else{
if(node_colors[neigh] == color) return false;
}
}
}
}
return true;
}
};
c++版本dfs
class Solution {
public:
bool helper(int node,int color,vector<vector<int>>& graph,vector<int>& node_colors){
if(node_colors[node] != -2 && color != node_colors[node]) return false;
if(node_colors[node] != -2 && color == node_colors[node]) return true;
node_colors[node] = color;
bool res = true;
for(auto& neigh : graph[node]){
res = res && helper(neigh,node_colors[node]*-1,graph,node_colors);
}
return res;
}
bool isBipartite(vector<vector<int>>& graph) {
int n = graph.size();
vector<int> node_colors(n,-2);
for(int node=0;node<n;node++){
if(node_colors[node] != -2) continue;
if(!helper(node,1,graph,node_colors)) return false;
}
return true;
}
};
good question to ask during interview
- will the graph be fully connected. i.e. there may be two nodes u and v such that there is no path between them?
- All the values of graph[u] are unique?
- undirected edge?