1. 程式人生 > >LeetCode 題解:785. Is Graph Bipartite?

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; } };