Is Graph Bipartite?
https://leetcode.com/problems/is-graph-bipartite/description/
给定图能否二分,即能找出两个集合,使得每个边的两点分别在两个集合。从任意一点开始染色,把它的邻居染成和它对立的颜色,DFS/BFS依次类推。当遇到邻居已经有色且与当前结点颜色相同,说明不可二分。大图里可能有多个联通子图,因此要遍历每个结点检查一遍。
Code
/*
* @lc app=leetcode id=785 lang=cpp
*
* [785] Is Graph Bipartite?
*
* https://leetcode.com/problems/is-graph-bipartite/description/
*
* algorithms
* Medium (44.36%)
* Likes: 817
* Dislikes: 103
* Total Accepted: 62K
* Total Submissions: 138.2K
* Testcase Example: '[[1,3],[0,2],[1,3],[0,2]]'
*
* 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
* Explanation:
* The graph looks like this:
* 0----1
* | |
* | |
* 3----2
* We can divide the vertices into two groups: {0, 2} and {1, 3}.
*
*
*
* Example 2:
* Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
* Output: false
* Explanation:
* The graph looks like this:
* 0----1
* | \ |
* | \ |
* 3----2
* We cannot find a way to divide the set of nodes into two independent
* subsets.
*
*
*
*
* Note:
*
*
* graph will have length in range [1, 100].
* graph[i] will contain integers in range [0, graph.length - 1].
* graph[i] will not contain i or duplicate values.
* The graph is undirected: if any element j is in graph[i], then i will be in
* graph[j].
*
*
*/
// @lc code=start
class Solution {
public:
bool dfs(int i, bool c, vector<vector<int>> &g, unordered_map<int, bool> &colors) {
if (colors.count(i)) {
return colors[i] == c;
}
colors[i] = c;
for (const auto &e : g[i]) {
if (!dfs(e, !c, g, colors)) return false;
}
return true;
}
bool isBipartite(vector<vector<int>>& graph) {
unordered_map<int, bool> colors;
for (int i = 0; i < graph.size(); ++i) {
if (!colors.count(i) && !dfs(i, false, graph, colors)) return false;
}
return true;
}
};
// @lc code=end
class Solution {
public boolean isBipartite(int[][] graph) {
Map<Integer, Integer> color = new HashMap<>();
for (int i = 0; i < graph.length; i++) {
if (!color.containsKey(i) && !dfs(i, 0, graph, color)) {
return false;
}
}
return true;
}
private boolean dfs(int i, int c, int[][] g, Map<Integer, Integer> color) {
if (color.containsKey(i)) {
if (color.get(i) != c) {
return false;
}
return true;
}
color.put(i, c);
for (int nei : g[i]) {
if (!dfs(nei, c ^ 1, g, color)) {
return false;
}
}
return true;
}
}
class Solution {
public boolean isBipartite(int[][] graph) {
Map<Integer, Integer> color = new HashMap<>();
for (int i = 0; i < graph.length; i++) {
if (!color.containsKey(i) && !bfs(i, graph, color)) {
return false;
}
}
return true;
}
private boolean bfs(int i, int[][] g, Map<Integer, Integer> color) {
Queue<Integer> queue = new LinkedList<>();
queue.offer(i);
int c = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int j = 0; j < size; j++) {
int val = queue.poll();
if (color.containsKey(val)) {
if (c != color.get(val)) {
return false;
}
} else {
color.put(val, c);
for (int nei : g[val]) {
queue.offer(nei);
}
}
}
c ^= 1;
}
return true;
}
}
Analysis
时间复杂度O(N + E), 每个节点和边各遍历一次。
Last updated
Was this helpful?