一【题目类别】
二【题目难度】
三【题目编号】
四【题目描述】
存在一个 无向图 ,图中有 n 个节点。其中每个节点都有一个介于 0 到 n - 1 之间的唯一编号。给你一个二维数组 graph ,其中 graph[u] 是一个节点数组,由节点 u 的邻接节点组成。形式上,对于 graph[u] 中的每个 v ,都存在一条位于节点 u 和节点 v 之间的无向边。该无向图同时具有以下属性: 不存在自环(graph[u] 不包含 u)。 不存在平行边(graph[u] 不包含重复值)。 如果 v 在 graph[u] 内,那么 u 也应该在 graph[v] 内(该图是无向图) 这个图可能不是连通图,也就是说两个节点 u 和 v 之间可能不存在一条连通彼此的路径。 二分图 定义:如果能将一个图的节点集合分割成两个独立的子集 A 和 B ,并使图中的每一条边的两个节点一个来自 A 集合,一个来自 B 集合,就将这个图称为 二分图 。 如果图是二分图,返回 true ;否则,返回 false 。
五【题目示例】
示例 1: 输入:graph = [[1,2,3],[0,2],[0,1,3],[0,2]] 输出:false 解释:不能将节点分割成两个独立的子集,以使每条边都连通一个子集中的一个节点与另一个子集中的一个节点。 示例 2: 输入:graph = [[1,3],[0,2],[1,3],[0,2]] 输出:true 解释:可以将节点分成两组: {0, 2} 和 {1, 3} 。
六【题目提示】
graph.length == n 1 <= n <= 100 0 <= graph[u].length < n 0 <= graph[u][i] <= n - 1 graph[u] 不会包含 u graph[u] 的所有值 互不相同 如果 graph[u] 包含 v,那么 graph[v] 也会包含 u
七【解题思路】
将每个节点的邻接结点染色为相反的颜色,如果是二分图那么肯定最后整个图为两个不同的颜色,如果不是二分图,也就是有一个环,所以在染色的过程中遇到当前结点和他的邻接结点颜色相同,说明之前他的邻居已经给他染色了,而且归位了同一个集合,现在当前结点又想把自己和之前的邻居归为另一个集合,因为要保证每个节点和自己的邻居结点不能是同一个颜色,因为题目要求每条边的两个结点是两个不同的集合,所以就不是二分图了
八【时间频度】
时间复杂度:
O
(
M
+
N
)
O(M+N)
O ( M + N ) ,
M
M
M 是结点个数,
N
N
N 是边的个数
九【代码实现】
Java语言版
package Graph;
public class p785_IsGraphBipartite {
public static void main ( String[ ] args) {
int [ ] [ ] graph = {
{ 1 , 2 , 3 } ,
{ 0 , 2 } ,
{ 0 , 1 , 3 } ,
{ 0 , 2 } ,
} ;
boolean res = isBipartite ( graph) ;
System. out. println ( "res = " + res) ;
}
public static boolean isBipartite ( int [ ] [ ] graph) {
if ( graph == null || graph. length == 0 ) {
return false ;
}
int v = graph. length;
int [ ] colors = new int [ v] ;
for ( int i = 0 ; i < v; i++ ) {
if ( ! dfs ( graph, i, colors, 0 ) ) {
return false ;
}
}
return true ;
}
public static boolean dfs ( int [ ] [ ] graph, int i, int [ ] colors, int lastColor) {
if ( colors[ i] != 0 ) {
return colors[ i] != lastColor;
}
colors[ i] = lastColor == 1 ? 2 : 1 ;
for ( int j = 0 ; j < graph[ i] . length; j++ ) {
if ( ! dfs ( graph, graph[ i] [ j] , colors, colors[ i] ) ) {
return false ;
}
}
return true ;
}
}
C语言版
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int bool;
#define false 0
#define true 1
enum color
{
unknown,
white,
black
} ;
bool isBipartite ( int * * graph, int graphSize, int * graphColSize)
{
int * pVisited = ( int * ) malloc ( graphSize * sizeof ( int ) ) ;
memset ( pVisited, 0 , graphSize * sizeof ( int ) ) ;
int * pQueue = ( int * ) malloc ( graphSize * sizeof ( int ) ) ;
int front = - 1 ;
int rear = - 1 ;
int curr = 0 ;
int row = 0 ;
int col = 0 ;
int neighborColor = 0 ;
for ( row = 0 ; row <= graphSize - 1 ; row++ )
{
if ( unknown != pVisited[ row] )
{
continue ;
}
pQueue[ ++ rear] = row;
pVisited[ row] = white;
while ( front != rear)
{
curr = pQueue[ ++ front] ;
neighborColor = pVisited[ curr] == white ? black : white;
for ( col = 0 ; col <= graphColSize[ curr] - 1 ; col++ )
{
if ( unknown == pVisited[ graph[ curr] [ col] ] )
{
pVisited[ graph[ curr] [ col] ] = neighborColor;
}
else if ( neighborColor != pVisited[ graph[ curr] [ col] ] )
{
return false;
}
}
}
}
return true;
}
十【提交结果】
Java语言版 C语言版