天天看點

LeetCode785 判斷二分圖LeetCode785 判斷二分圖

LeetCode785 判斷二分圖

題目

存在一個無向圖,圖中有 n 個節點。其中每個節點都有一個介于 0 到 n - 1 之間的唯一編号。給你一個二維數組 graph ,其中 graph[u] 是一個節點數組,由節點 u 的鄰接節點組成。形式上,對于 graph[u] 中的每個 v ,都存在一條位于節點 u 和節點 v 之間的無向邊。該無向圖同時具有以下屬性:

  • 不存在自環(graph[u] 不包含 u)。
  • 不存在平行邊(graph[u] 不包含重複值)。
  • 如果 v 在 graph[u] 内,那麼 u 也應該在 graph[v] 内(該圖是無向圖)
  • 這個圖可能不是連通圖,也就是說兩個節點 u 和 v 之間可能不存在一條連通彼此的路徑。

二分圖定義:如果能将一個圖的節點集合分割成兩個獨立的子集 A 和 B ,并使圖中的每一條邊的兩個節點一個來自 A 集合,一個來自 B 集合,就将這個圖稱為 二分圖 。

如果圖是二分圖,傳回 true ;否則,傳回 false 。

示例 1:不是一個二分圖

LeetCode785 判斷二分圖LeetCode785 判斷二分圖

示例二:是一個二分圖

LeetCode785 判斷二分圖LeetCode785 判斷二分圖

解題思路

這是一道判斷是否是二分圖的題目,類似于圖着色,可以抽象成能不能将圖中的每條邊的兩個節點塗上不同的顔色。關于二分圖的知識可以看我的另一篇部落格圖結構專欄——判斷二分圖。這道題可以用dfs和bfs兩種方法解決。

2.1 深度優先周遊

vector<int> visited;
	bool ok = true;
	void dfs(vector<vector<int>>& graph, int thisnode, int lastnode)
	{
		if (lastnode == -1)
		{

		}
		else
		{
			if (visited[thisnode] == -1)//這個節點還未通路
			{
				visited[thisnode] = visited[lastnode] ^ 1;
			}
			else//這個節點通路過
			{
				if (visited[thisnode] ^ 1 != visited[lastnode])
				{
					ok = false;
				}
				return;
			}
		}
		for (int i = 0; i < graph[thisnode].size(); i++)
		{
			dfs(graph, graph[thisnode][i], thisnode);
		}
	}
	//參數graph:graph[i]是一個容器,裝有與節點i相連的節點
	bool isBipartite(vector<vector<int>>& graph) {
		visited.resize(graph.size(), -1);
		for (int i = 0; i < graph.size(); i++)
		{
			if (visited[i] == -1)
			{
				visited[i] = 0;
				dfs(graph, i, -1);
			}
		}
		return ok;
	}
           

2.2廣度優先周遊

class Solution {
public:
	vector<int> visited;

	bool isBipartite(vector<vector<int>>& graph) {
		visited.resize(graph.size(), -1);
		queue<int> q;
		for (int i = 0; i < graph.size(); i++)
		{
			if (visited[i] == -1)
			{
				visited[i] = 0;
				q.push(i);
				while (!q.empty())
				{
					int thisnode = q.front();
					q.pop();
					for (int j = 0; j < graph[thisnode].size(); j++)
					{
						if (visited[graph[thisnode][j]] != -1)
						{
							if (visited[graph[thisnode][j]] == visited[thisnode])
								return false;
						}
						else
						{
							visited[graph[thisnode][j]] = visited[thisnode] ^ 1;
							q.push(graph[thisnode][j]);
						}
					}
				}
			}
		}
		return true;
	}
};