2020.7.16 力扣每日

 

 1 class Solution {
 2     private int[] num;
 3     public boolean isBipartite(int[][] graph) {
 4         num = new int[graph.length];
 5         Arrays.fill(num, -1);
 6         for (int i = 0; i < graph.length; i++){
 7             if (num[i] == -1)
 8                 num[i] = 0;
 9             else continue;
10             if(dfs(i, num, graph)==false)
11                 return false;
12         }
13         return true;
14     }
15     public boolean dfs(int i, int[] num, int[][] graph){
16         for( int j = 0; j < graph[i].length; j++){
17             int now = graph[i][j];
18             if(num[now] == -1){
19                 num[now] = 1 - num[i];
20                 if (dfs(graph[i][j], num, graph) == false)
21                     return false;
22             }
23             if (num[now] == num[i])
24                 return  false;
25         }
26         return true;
27     }
28 }

解题思路:

    题目要求判断给定数组的无向图是否为二分图,显然我们需要遍历图,遍历图的方法一般分为BFSDFS,此处我们采用DFS来遍历。

    根据二分图的性质,相邻节点属于不同集合,如果集合A标记为0,集合B标记为1,则代表图中所有的节点与其相邻节点必须为0与1。此时,我们便可以设计算法了,选定0节点为起始节点,标记为0,使用dfs依次遍历,未遍历到的节点标记为-1,遍历到的节点值为 1-根节点标记,如果该点值不为-1,则判断其与根节点是否相同,相同返回false,递归调用dfs遍历完以0节点起始的图。

注意点:

    以上算法显然仅适用于0节点存在,且所有的节点均可连接至0节点的情况。而实际情况中可能有部分节点单独独立于0节点,甚至可能部分独立的节点相互连接形成新的图,此时该算法便无法处理,我们对算法进行优化。

    利用for循环遍历图中的每一个节点i,将其作为参数传入dfs,判断其节点标记是否为-1,为-1则标记为0,利用dfs遍历以该节点为起点的图,不为-1则表明包含该点的图已经为二分图了,则跳过该节点i++,继续遍历其余节点,直到遍历完所有的节点,求出最终结果。

时间复杂度O(m+n),m,n分别为节点数与路径条数

空间复杂度O(n),n为节点数,用于标记节点状态

题后总结:

    优:使用了递归的方法实现dfs遍历节点,且考虑了特殊的情况。

    差:对于递归判断状态起初考虑不周,在节点标记为-1处,直接return dfs(graph[i][j], num, graph),导致若一条路径结果为true,就不再遍历其余路径了。

posted @ 2020-07-16 22:50  小小码农-安  阅读(188)  评论(0)    收藏  举报