求细胞数量
题目描述
一矩形阵列由数字 0 0 0 到 9 9 9 组成,数字 1 1 1 到 9 9 9 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。
输入格式
第一行两个整数代表矩阵大小 n n n 和 m m m。
接下来
n
n
n 行,每行一个长度为
m
m
m 的只含字符 0
到 9
的字符串,代表这个
n
×
m
n \times m
n×m 的矩阵。
输出格式
一行一个整数代表细胞个数。
样例 #1
样例输入 #1
4 10
0234500067
1034560500
2045600671
0000000089
样例输出 #1
4
提示
数据规模与约定
对于 100 % 100\% 100% 的数据,保证 1 ≤ n , m ≤ 100 1 \le n,m \le 100 1≤n,m≤100。
题解
这个题和leetcode一道题非常非常像,和洛谷另外一套题也很像,大家也可以去看一下这两道题:
leetcode:200. 岛屿数量
洛谷:P1596 [USACO10OCT] Lake Counting S
这种题很明显是求连通分量的题,而图是用一个网格矩阵存储的。我写了两种DFS Python代码来求解这道题:
第一种的思路就是用一个visited数组,存储是否访问过这个坐标的数字,如果访问过就不再访问,这样后续就不会再访问到同一个连通分量
class Solution:
def numCells(self) -> int:
h, w = map(int, input().strip().split())
grid = []
for i in range(h):
values = [i for i in input().strip()]
grid.append(values)
vis = [[False for _ in range(w)] for _ in range(h)]
def dfs(x, y):
if grid[x][y] == "0":
return
if vis[x][y] == True:
return
vis[x][y] = True
# 向右遍历
if y+1 < w:
dfs(x, y+1)
# 向下遍历
if x+1 < h:
dfs(x+1, y)
# 向左遍历
if y-1 > -1:
dfs(x, y-1)
# 向上遍历
if x-1 > -1:
dfs(x-1, y)
return "break"
res = 0
for x in range(h):
for y in range(w):
if grid[x][y] != '0' and vis[x][y] == False:
dfs(x, y)
res += 1
return res
s = Solution()
print(s.numCells())
第二种思路就是,每访问一个细胞(连通分量),我就把这个细胞(连通分量)所有元素都消除掉,这样后续肯定不能再次访问这个细胞(连通分量)了
def dfs(graph, i, j):
if graph[i][j] != '0':
graph[i][j] = '0'
if i-1 > -1:
dfs(graph, i-1, j)
if j-1 > -1:
dfs(graph, i, j-1)
if i+1 < len(graph):
dfs(graph, i+1, j)
if j+1 < len(graph[0]):
dfs(graph, i, j+1)
def Solution():
N, M = map(int, input().strip().split())
graph = []
for i in range(N):
graph.append([i for i in input().strip()])
ans = 0
for i in range(N):
for j in range(M):
if graph[i][j] != '0':
# 周围一圈入队列,检测是否超出范围即可
dfs(graph, i, j)
ans += 1
return ans
print(Solution())
第二种思路DFS空间开销更小,其余的内容差不太多