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 it’s 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: [[1,3], [0,2], [1,3], [0,2]]
Output: true

Example 2:
Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
Output: false

解题思路

本题是判断一个无向图是否为二分图,我使用染色法进行相邻节点的判断,并采取BFS进行图的遍历

  1. 初始化保存颜色的数组 color(0表示白色,1表示黑色,-1表示未染色),建立BFS队列以及判断该节点是否被遍历过的状态数组 check
  2. 从任意节点开始进行遍历,将该节点添加到BFS队列,颜色设为1,check 状态为true(我选择了0号节点)
  3. 每次从BFS队列中取出一个新节点,若该节点的子节点未被访问过(染色),那么将其染成与当前节点相反的颜色,并将这个子节点添加到BFS队列的尾部,设置 check 状态为true;否则,检查该子节点的颜色与当前节点是否相同,若相同,说明图中出现了奇数边的环,那么这个图不是二分图,返回false,结束
  4. 由于测试样例中有无出度的节点,因此在BFS队列为空的时候要检查一下状态数组 check 中是否还有未遍历的节点;若有,将其添加到BFS队列,继续遍历
  5. 当所有节点已经访问完毕,没有出现颜色重复的节点,说明这个图是二分图,返回true

C++代码

class Solution {
public:
    bool isBipartite(vector<vector<int>>& graph) {
        vector<int> color(graph.size(), -1);
        queue<int> bfs_queue;
        vector<bool> check(graph.size(), false);
        
        color[0] = 1;
        bfs_queue.push(0);
        check[0] = true;
        
        while(!bfs_queue.empty()) {
            int p = bfs_queue.front();
            bfs_queue.pop();
            for(int i = 0; i < graph[p].size(); i++){
                if(color[graph[p][i]] == -1){
                    color[graph[p][i]] = color[p] == 1? 0 : 1;
                    bfs_queue.push(graph[p][i]);
                    check[graph[p][i]] = true;
                }
                if(color[graph[p][i]] == color[p])
                    return false;
            }
            
            if(bfs_queue.empty()) {
                for(int i = 0; i < check.size(); i++) {
                    if(!check[i]) {
                        bfs_queue.push(i);
                        color[i] = 1;
                        check[i] = true;
                        break;
                    }
                }
            }
        }
        return true;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ZTao-z

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

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

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

打赏作者

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

抵扣说明:

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

余额充值