图 - 二分图 - 判断是否为二分图

1.题目

LeetCode: 785. 判断二分图

【medium】

2.解题

方法一:DFS

根据题意,图中任意两个相连的节点必定属于不同的集合。我们可以通过染色的方式进行解答,从任意一个节点开始,将其染成红色(0),然后将他相连的其他节点都染成绿色(1),然后遍历下一个节点,如果是绿色就将其相连的节点染成红色,否则染成绿色,以此类推,直到遍历完所有节点,如果产生冲突即本该染红色的节点已经被染成了绿色,则直接返回false,不符合二分图,反之亦然。

算法的流程如下:

  • 我们任选一个节点开始,将其染成红色,并从该节点开始对整个无向图进行遍历;
  • 在遍历的过程中,如果我们通过节点 u 遍历到了节点 v(即 u 和 v 在图中有一条边直接相连),那么会有两种情况:
  • 如果 v 未被染色,那么我们将其染成与 u 不同的颜色,并对 v 直接相连的节点进行遍历;
  • 如果 v 被染色,并且颜色与 u 相同,那么说明给定的无向图不是二分图。我们可以直接退出遍历并返回 False 作为答案。
  • 当遍历结束时,说明给定的无向图是二分图,返回 True 作为答案。

java:

class Solution {
    public boolean isBipartite(int[][] graph) {
        int[] color = new int[graph.length];
        Arrays.fill(color, -1);
        for (int i = 0; i < graph.length; i++) {
            if (color[i] == -1 && !dfs(i, 0, color, graph)) return false;
        }
        return true;
    }

    public boolean dfs(int i, int c, int[] color, int[][] graph) {
        if (color[i] != -1) return color[i] == c;
        color[i] = c;
        for (int node : graph[i]) {
            if (!dfs(node, 1 - c, color, graph)) return false;
        }
        return true;
    }
}

时间复杂度:O(m + n),m和n分别的无向图的点数和边数

空间复杂度:O(m),递归栈所用空间

方法二:BFS

java:

class Solution {
    public boolean isBipartite(int[][] graph) {
        int[] color = new int[graph.length];
        Arrays.fill(color, -1);
        int c = 0;
        for (int i = 0; i < graph.length; ++i) {
            if (color[i] == -1) {
                Queue<Integer> queue = new LinkedList<>();
                queue.offer(i);
                color[i] = c;
                while (!queue.isEmpty()) {
                    int node = queue.poll();
                    int c2 = color[node] == c ? 1 - c : c;
                    for (int next_node : graph[node]) {
                        if (color[next_node] == -1) {
                            queue.offer(next_node);
                            color[next_node] = c2;
                        } else if (color[next_node] != c2) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值