785. 判斷二分圖
給定一個無向圖graph
,當這個圖為二分圖時返回true
。
如果我們能將一個圖的節點集合分割成兩個獨立的子集A和B,並使圖中的每一條邊的兩個節點一個來自A集合,一個來自B集合,我們就將這個圖稱為二分圖。
graph
將會以鄰接表方式給出,graph[i]
表示圖中與節點i
相連的所有節點。每個節點都是一個在0
到graph.length-1
之間的整數。這圖中沒有自環和平行邊: graph[i]
中不存在i
,並且graph[i]
中沒有重復的值。
示例 1:
輸入: [[1,3], [0,2], [1,3], [0,2]]
輸出: true
解釋:
無向圖如下:
0----1
| |
| |
3----2
我們可以將節點分成兩組: {0, 2} 和 {1, 3}。
示例 2: 輸入: [[1,2,3], [0,2], [0,1,3], [0,2]] 輸出: false 解釋: 無向圖如下: 0----1 | \ | | \ | 3----2 我們不能將節點分割成兩個獨立的子集。
二分圖又稱作二部圖,是圖論中的一種特殊模型。 設G=(V,E)是一個無向圖,如果頂點V可分割為兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A,j in B),則稱圖G為一個二分圖。
簡而言之,就是頂點集V可分割為兩個互不相交的子集,並且圖中每條邊依附的兩個頂點都分屬於這兩個互不相交的子集,兩個子集內的頂點不相鄰。
區別二分圖,關鍵是看點集是否能分成兩個獨立的點集。
上圖中U和V構造的點集所形成的循環圈不為奇數,所以是二分圖。
上圖中U和V和W構造的點集所形成的的循環圈為奇數,所以不是二分圖。
方法一:深度優先搜索着色【通過】
思路
如果節點屬於第一個集合,將其着為藍色,否則着為紅色。只有在二分圖的情況下,可以使用貪心思想給圖着色:一個節點為藍色,說明它的所有鄰接點為紅色,它的鄰接點的所有鄰接點為藍色,依此類推。
算法
使用數組(或者哈希表)記錄每個節點的顏色: color[node]。顏色可以是 0, 1,或者未着色(-1 或者 null)。
搜索節點時,需要考慮圖是非連通的情況。對每個未着色節點,從該節點開始深度優先搜索着色。每個鄰接點都可以通過當前節點着相反的顏色。如果存在當前點和鄰接點顏色相同,則着色失敗。
使用棧完成深度優先搜索,棧類似於節點的 “todo list”,存儲着下一個要訪問節點的順序。在 graph[node] 中,對每個未着色鄰接點,着色該節點並將其放入到棧中。
class Solution(object):
def isBipartite(self, graph):
color = {}
for node in xrange(len(graph)):
if node not in color:
stack = [node]
color[node] = 0
while stack:
node = stack.pop()
for nei in graph[node]:
if nei not in color:
stack.append(nei)
color[nei] = color[node] ^ 1
elif color[nei] == color[node]:
return False
return True
復雜度分析
時間復雜度:O(N+E)O(N + E)O(N+E),其中 NNN 是節點的數量,EEE 是邊的數量。着色每個節點時,遍歷其所有邊。
空間復雜度:O(N)O(N)O(N),存儲 color 的棧。
作者:LeetCode
鏈接:https://leetcode-cn.com/problems/is-graph-bipartite/solution/pan-duan-er-fen-tu-by-leetcode/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
思路
如果節點屬於第一個集合,將其着為藍色,否則着為紅色。只有在二分圖的情況下,可以使用貪心思想給圖着色:一個節點為藍色,說明它的所有鄰接點為紅色,它的鄰接點的所有鄰接點為藍色,依此類推。
算法
使用數組(或者哈希表)記錄每個節點的顏色: color[node]。顏色可以是 0, 1,或者未着色(-1 或者 null)。
搜索節點時,需要考慮圖是非連通的情況。對每個未着色節點,從該節點開始深度優先搜索着色。每個鄰接點都可以通過當前節點着相反的顏色。如果存在當前點和鄰接點顏色相同,則着色失敗。
使用棧完成深度優先搜索,棧類似於節點的 “todo list”,存儲着下一個要訪問節點的順序。在 graph[node] 中,對每個未着色鄰接點,着色該節點並將其放入到棧中。
class Solution(object):
def isBipartite(self, graph):
color = {}
for node in xrange(len(graph)):
if node not in color:
stack = [node]
color[node] = 0
while stack:
node = stack.pop()
for nei in graph[node]:
if nei not in color:
stack.append(nei)
color[nei] = color[node] ^ 1
elif color[nei] == color[node]:
return False
return True
復雜度分析
時間復雜度:O(N+E)O(N + E)O(N+E),其中 NNN 是節點的數量,EEE 是邊的數量。着色每個節點時,遍歷其所有邊。
空間復雜度:O(N)O(N)O(N),存儲 color 的棧。
作者:LeetCode
鏈接:https://leetcode-cn.com/problems/is-graph-bipartite/solution/pan-duan-er-fen-tu-by-leetcode/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。