题目:​​原题链接​(困难)

标签:图、广度优先搜索、贪心算法

解法

时间复杂度

空间复杂度

执行用时

Ans 1 (Python)

O ( N 2 )

O ( N )

56ms (22.67%)

Ans 2 (Python)

Ans 3 (Python)

解法一:

class Solution:
def domino(self, n: int, m: int, broken: List[List[int]]) -> int:
def is_valid(x, y):
return 0 <= x < n and 0 <= y < m and (x, y) not in broken

def get_near(x, y):
return [(x1, y1) for (x1, y1) in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)] if is_valid(x1, y1)]

visited = [[False] * m for _ in range(n)]
broken = set((i, j) for (i, j) in broken)

ans = 0

for i in range(n):
for j in range(m):
if not visited[i][j] and (i, j) not in broken:
# 广度优先搜索遍历当前区域
visited[i][j] = True
queue = collections.deque([(i, j)])
points = [(i, j)]
while queue:
i1, j1 = queue.popleft()
for i2, j2 in get_near(i1, j1):
if not visited[i2][j2]:
visited[i2][j2] = True
queue.append((i2, j2))
points.append((i2, j2))

# 思路:二分图中黑点和白点 + 贪心算法,从只有一个选择的点开始选择

# 构造图
graph = {point: set() for point in points}
for (i1, j1) in graph:
for i2, j2 in get_near(i1, j1):
graph[(i1, j1)].add((i2, j2))

# 贪心选择
while len(graph) >= 2:
for (i1, j1) in list(graph.keys()):
for i2, j2 in list(graph[(i1, j1)]):
if (i2, j2) not in graph:
graph[(i1, j1)].remove((i2, j2))
if len(graph[(i1, j1)]) == 0:
del graph[(i1, j1)]

min_idx, min_val = (-1, -1), 5
for (i1, j1) in list(graph.keys()):
if len(graph[(i1, j1)]) < min_val:
min_idx, min_val = (i1, j1), len(graph[i1, j1])
if min_val == 1:
break

if min_val < 5:
i1, j1 = min_idx
i2, j2 = graph[min_idx].pop()

del graph[(i1, j1)]
del graph[(i2, j2)]
ans += 1

return ans