leetcode 785. Is Graph Bipartite?(二分图)

Given an undirected graph, return true if and only if it is bipartite.

Recall that a graph is bipartite if we can split its set of nodes into two independent subsets A and B, such that every edge in the graph has one node in A and another node in B.

The graph is given in the following form: graph[i] is a list of indexes j for which the edge between nodes i and j exists. Each node is an integer between 0 and graph.length - 1. There are no self edges or parallel edges: graph[i] does not contain i, and it doesn’t contain any element twice.

Example 1:
在这里插入图片描述
Input: graph = [[1,3],[0,2],[1,3],[0,2]]
Output: true
Explanation: We can divide the vertices into two groups: {0, 2} and {1, 3}.

Constraints:
1 <= graph.length <= 100
0 <= graph[i].length < 100
0 <= graph[i][j] <= graph.length - 1
graph[i][j] != i
All the values of graph[i] are unique.
The graph is guaranteed to be undirected.

无向图,问图是否为二分图。
二分图可以理解为给图的顶点染两种颜色,一条边的两个顶点不能是同一种颜色。

思路:
假设给图的顶点染两种颜色,分别为颜色1和颜色2
还没有染色的node染上颜色1,那这个node连接的另一头顶点要染上颜色2。
BFS遍历graph,如果中间出现颜色矛盾的情况就返回false。
定义group数组保存每个node的颜色。
注意每个顶点都要遍历。

    public boolean isBipartite(int[][] graph) {
        int n = graph.length;
        int[] group = new int[n];
        for(int i = 0; i < n; i++) {
            if(group[i] == 0 && !bfs(i, graph, n, group)) return false;
        }
        
        return true;
    }
    
    boolean bfs(int cur, int[][] graph, int n, int[] group) {
        
        Queue<Integer> queue = new LinkedList<>();
        
        queue.offer(cur);
        if(group[cur] == 0) group[cur] = 1;
        
        while(!queue.isEmpty()) {
            int node = queue.poll();
            int nextGroup = group[node] == 1 ? 2 : 1;
            for(int nextNode : graph[node]) {
                if(group[nextNode] == 0) {
                    group[nextNode] = nextGroup;
                    queue.offer(nextNode);
                } else if(group[nextNode] != nextGroup) {
                    return false;
                }
            }
        }
        
        return true;
    }

方法2: DFS
因为只有两种颜色,可以利用正负数翻转来预测下一个颜色,如果出现矛盾则返回false。

class Solution {
    public boolean isBipartite(int[][] graph) {
        int n = graph.length;
        int[] colors = new int[n];
        
        for(int i = 0; i < n; i ++) {
            if(colors[i] == 0 && !dfs(graph, colors, i, 1)) return false;
        }
        return true;
    }
    
    boolean dfs(int[][] graph, int[] colors, int i, int color) {
        if(colors[i] != 0) return colors[i] == color;
        colors[i] = color;
        for(int nxt : graph[i]) {
            if(!dfs(graph, colors, nxt, -color)) return false;
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值