leetcode判断二分图

判断二分图

图的问题肯定要用到深度优先遍历或者广度优先遍历,但又不是单纯的深度优先遍历算法和广度优先遍历算法,而是需要在遍历的过程中加入与解决题目相关的逻辑。

题干中说了,这个图可能不是连通图,这个提示有什么作用呢?

很多时候我们接触的题目,图都是连通的,对于连通图来说,从一个点开始遍历,不管是深度优先还是广度优先,遍历一遍就可以把图中的所有点都遍历到;而对于非连通图来说,从一个点开始遍历,就无法将所有点都遍历一遍,这就需要针对每个点都进行一次遍历。


不管使用深度优先遍历算法还是使用广度优先遍历算法,都要实时记录结果,如果当前已经确定了不是连通图,那么说明结果已经确定了,就不需要继续判断,直接返回就可以。因为已经判断不是连通图,那么再继续判断下去没有意义,不是连通图的情况已经确定;如果在判断过程中,一直是连通图,那么还有没有遍历到的点,还是需要继续遍历的,因为剩下的点可能是不连通的。

1 深度优先遍历算法

class Solution {
public:
    enum Color {
        kUnColored = 0,
        kRed = 1,
        kGreen = 2
    };
    // 如果已经确定不是连通图了,就不需要继续遍历了
    bool isBipartite(vector<vector<int>>& graph) {
      int size = graph.size();
      // 图可能是非连通图,所以需要从每个节点开始进行一次遍历
      for (int i = 0; i < size && result == true; i++) {
        // 如果这个点没有遍历到,那么才需要遍历,已经遍历到的不需要继续遍历
        if (dataColor[i] == Color::kUnColored) {
          dfsScanGraph(graph, i, Color::kRed);
        }
      }
      return result;
    }

    void dfsScanGraph(vector<vector<int>> &graph, int const node, Color const color) {
       if (result == false) {
           return;
       }
       dataColor[node] = color;
       const Color line_color{color == Color::kRed ? Color::kGreen : Color::kRed};
       
       //给node连接的这一行的节点染色
       for (int data : graph[node]) {
         if (result == false) {
            return;
         }
         // 1、如果与node颜色相同,那么这两者属于同一个区域,可以确定不是二分图
         // 2、如果这个点还没有染色,那么进行递归染色,颜色与node不同的颜色
         // 3、如果节点已经染色,并且与node颜色不同,那么不做处理
         if (dataColor[data] == color) {
            result = false;
            return;
         } else if (dataColor[data] == Color::kUnColored){
            dfsScanGraph(graph, data, line_color);  
         }
       }
    }

private:
  int dataColor[101] = {0};
  bool result = true;
};

2 广度优先遍历算法

class Solution {
public:
    enum Color {
        kUnColored = 0,
        kRed = 1,
        kGreen = 2
    };

    bool isBipartite(vector<vector<int>>& graph) {
      int size = graph.size();
      for (int i = 0; i < size && result == true; i++) {
          if (dataColor[i] == Color::kUnColored) {
              // 广度优先遍历需要使用一个队列来辅助
              // 每一次广度优先遍历,都使用一个新的,空的队列
              std::queue<int> queue;
              bfsScanGraph(graph, i, Color::kRed, queue);
          }
      }
      return result;
    }

    void bfsScanGraph(vector<vector<int>> &graph, int const data, Color const color,std::queue<int> &queue) {
        if (result == false) {
            return;
        }

        dataColor[data] = color;
        queue.push(data);

        
        while (!queue.empty()) {
            int head_data = queue.front();
            queue.pop();
            const Color another_color{dataColor[head_data] == Color::kRed ? Color::kGreen : Color::kRed};

            for (int line_data : graph[head_data]) {
                if (result == false) {
                    return;
                }

                if (dataColor[line_data] == Color::kUnColored) {
                    dataColor[line_data] = another_color;
                    queue.push(line_data);
                } else {
                    // 这里比较的对象与深度优先遍历中比较的是不一样的
                    // 深度优先比较的对象是node,广度优先比较的对象是出队的head_data
                    // 两者的相同点,比较的对象都是与这一行的行首进行比较,行首表示这与当前这个节点是临接点
                    if (dataColor[line_data] == dataColor[head_data]) {
                        result = false;
                        return;
                    }
                }
            }

        }
    }

private:
  int dataColor[101] = {0};
  bool result = true;
};

相关推荐

  1. 算法——论:判断二分(染色问题)

    2024-07-11 11:18:07       36 阅读
  2. <span style='color:red;'>二分</span><span style='color:red;'>图</span>

    二分

    2024-07-11 11:18:07      43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 11:18:07       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 11:18:07       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 11:18:07       58 阅读
  4. Python语言-面向对象

    2024-07-11 11:18:07       69 阅读

热门阅读

  1. 华为机试HJ84统计大写字母个数

    2024-07-11 11:18:07       20 阅读
  2. MySQL中in和exists的区别

    2024-07-11 11:18:07       20 阅读
  3. Spring Boot 常用 Starter

    2024-07-11 11:18:07       22 阅读
  4. dify/api/models/tool.py文件中的数据表

    2024-07-11 11:18:07       22 阅读
  5. 【SQL】InnoDB的意向锁

    2024-07-11 11:18:07       24 阅读
  6. SpringSecurity中文文档(Servlet OAuth 2.0 Client)

    2024-07-11 11:18:07       19 阅读
  7. Linux串口设备的使用<ubuntu>

    2024-07-11 11:18:07       21 阅读
  8. 计算机如何学习

    2024-07-11 11:18:07       19 阅读
  9. 【通信原理】matlab中pskmod的介绍

    2024-07-11 11:18:07       18 阅读
  10. Perl词法分析:构建编程语言解析器的指南

    2024-07-11 11:18:07       24 阅读
  11. Elasticsearch 搜索模板:重用和共享查询

    2024-07-11 11:18:07       25 阅读