思路:我们要求将点分为两部分,并且每一部分之间的点互不相连,首先对于一个点来说与其相邻的都标记为不同颜色,这样广度或者深度遍历下去,如果在标记的过程中发现一个点需要被标记为两个颜色或者与其相邻的点的颜色相同,则说明输入不可以被分成两个点集。
难点:没有想到什么时候可以判断无法分成两个互不相连的点集合,只想着从正面的怎么做可以分为两部分入手了,应该反向思考下;第二个点是对点的颜色做标记,0代表未访问,1代表划分为点集1,2代表划分为点集合2.
解法一:bfs
class Solution {
public boolean isBipartite(int[][] graph) {
if(graph.length<=1)
return true;
int color[]=new int[graph.length];
for(int i=0;i<graph.length;i++){
if(color[i]==0){
color[i]=1;
Queue<Integer> queue=new LinkedList<Integer>();
queue.offer(i);
while(queue.size()>0){
int t1=queue.poll();
for(int j=0;j<graph[t1].length;j++){
int t2=graph[t1][j];
if(color[t2]==0){
color[t2]=color[t1]==1?2:1;
queue.offer(t2);
}
else{
if(color[t1]==color[t2])
return false;
}
}
}
}
}
return true;
}
}
解法2:dfs
class Solution {
public boolean flag=true;
public boolean isBipartite(int[][] graph) {
if(graph.length<=1)
return true;
int color[]=new int[graph.length];
for(int i=0;i<graph.length;i++){
if(color[i]==0){
color[i]=1;
dfs(i,graph,color);
if(!flag)
return flag;
}
}
return flag;
}
void dfs(int pos,int graph[][],int color[]){
for(int j=0;j<graph[pos].length;j++){
int k=graph[pos][j];
if(color[k]==0){
color[k]=(color[pos]==1?2:1);
dfs(k,graph,color);
}else{
if(color[k]==color[pos]){
flag=false;
return;
}
}
}
}
}