Leetcode-785-判断二分图

题目

image.png

相关题:886-可能的二分法

题解

题解1:bfs

注意:存在多个连通域

// bfs
// 从各个连通域的任一顶点开始遍历整个连通域,遍历的过程中用两种不同的颜色对顶点进行染色,相邻顶点染成相反的颜色。这个过程中倘若发现相邻的顶点被染成了相同的颜色,说明它不是二分图;反之,如果所有的连通域都染色成功,说明它是二分图。
class Solution {
    public int[] color;
    public boolean isBipartite(int[][] graph) {
        if (graph == null || graph.length == 0) {
            return false;
        }
        // 初始值为 0 表示未被访问,赋值为 1 或者 -1 表示两种不同的颜色。
        color = new int[graph.length];
        Queue queue = new LinkedList<>();
        // 图中可能含有多个连通域,所以需要判断是否存在顶点未被访问,若存在则从它开始再进行一轮 bfs 染色
        for (int i = 0; i < graph.length; i++) {
            if (color[i] != 0) {
                continue;
            }
            // 每出队一个顶点,将其所有邻接点染成相反的颜色并入队
            queue.offer(i);
            color[i] = 1;
            while (!queue.isEmpty()) {
                int top = queue.poll();
                for (int w : graph[top]) {
                    // 如果当前顶点的某个邻接点已经被染过色了,且颜色和当前顶点相同,说明此无向图无法被正确染色,返回 false
                    if (color[w] == color[top]) {
                        return false;
                    }
                    if (color[w] == 0) {
                        color[w] = - color[top];
                        queue.add(w);
                    }
                }
            }
        }
        // queue.add(0);
        // color[0] = 1;
        // // visited[0] = true;
        // while (!queue.isEmpty()) {
        //     int top = queue.poll();
        //     int preColor = color[top];
        //     for (int i : graph[top]) {
        //         if (i == top) {         // 自环
        //             return false;
        //         }
        //         if (color[i] == 0) {
        //             // visited[i] = true;
        //             queue.add(i);
        //             if (color[i] != 0) {
        //                 if (color[i] != -preColor) {
        //                     return false;
        //                 }
        //             }
        //             color[i] = -preColor;
        //         }
        //     }
        // }
        return true;
    }
}
题解2:dfs
// dfs
class Solution {
    public boolean isBipartite(int[][] graph) {
        // 初始值为 0 表示未被访问,赋值为 1 或者 -1 表示两种不同的颜色
        int[] visited = new int[graph.length];
        // 图中可能含有多个连通域,所以我们需要判断是否存在顶点未被访问,若存在则从它开始再进行一轮 dfs 染色
        for (int i = 0; i < graph.length; i++) {
            if (visited[i] == 0 && !dfs(graph, i, 1, visited)) {
                return false;
            }
        }
        return true;
    }
    public boolean dfs(int[][] graph, int v, int color, int[] visited) {
        // 如果要对某顶点染色时,发现它已经被染色了,则判断它的颜色是否与本次要染的颜色相同,如果矛盾,说明此无向图无法被正确染色,返回 false
        if (visited[v] != 0) {
            return visited[v] == color;
        }
        // 对当前顶点进行染色,并将当前顶点的所有邻接点染成相反的颜色
        visited[v] = color;
        for (int w : graph[v]) {
            if (!dfs(graph, w, -color, visited)) {
                return false;
            }
        }
        return true;
    }
}
题解3:并查集

参考

https://leetcode-cn.com/problems/is-graph-bipartite/solution/bfs-dfs-bing-cha-ji-san-chong-fang-fa-pan-duan-er-/

你可能感兴趣的:(Leetcode-785-判断二分图)