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 }
解题思路:
题目要求判断给定数组的无向图是否为二分图,显然我们需要遍历图,遍历图的方法一般分为BFS与DFS,此处我们采用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,就不再遍历其余路径了。

浙公网安备 33010602011771号