1. 问题描述:
这里有一幅服务器分布图,服务器的位置标识在 m * n 的整数矩阵网格 grid 中,1 表示单元格上有服务器,0 表示没有。如果两台服务器位于同一行或者同一列,我们就认为它们之间可以进行通信。请你统计并返回能够与至少一台其他服务器进行通信的服务器的数量。
示例 1:
输入:grid = [[1,0],[0,1]]
输出:0
解释:没有一台服务器能与其他服务器进行通信
示例 2:
输入:grid = [[1,0],[1,1]]
输出:3
解释:所有这些服务器都至少可以与一台别的服务器进行通信
示例 3:
输入:grid = [[1,1,0,0],[0,0,1,0],[0,0,1,0],[0,0,0,1]]
输出:4
解释:第一行的两台服务器互相通信,第三列的两台服务器互相通信,但右下角的服务器无法与其他服务器通信。
提示:
m == grid.length
n == grid[i].length
1 <= m <= 250
1 <= n <= 250
grid[i][j] == 0 or 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-servers-that-communicate
2. 思路分析:
① 一开始看到这个想到的是与之类似的岛屿问题的解决思路,使用深搜(dfs)也就是从周围四个方向进行搜索,假如列表中的元素为1那么从下一个方向进行搜索,但是这里与岛屿问题不同的一个点是这里是同一行或者是同一列,所以我们在搜索的时候不是按照相邻的四个方向进行搜索一而是从同一行或者是同一列进行搜索,并且这里可以使用到与之前的水洼问题的处理方法,当访问过一个水洼的位置之后可以将其置为0这样就可以省略标记数组,解决重复访问的问题,这里也是可以这样处理,这个技巧使用到这里是非常巧妙的。
② 这里可以使用有返回值得dfs来解决,每访问一个1的位置进行计数最后范围当前位置往下进行递归的结果即可,所以我们在一开始的时候就需要声明一个变量来进行计数,最后返回这个变量的值即可。
③ 当我们做多了这样的题目之后可以发现遇到类似的题目我们只需要修改对应的处理细节即可,其中大部分的处理思路都是类似的。
3. 代码如下:
from typing import List
class Solution:
def countServers(self, grid: List[List[int]]) -> int:
# 对于每一个位置都是这样处理的所以可以使用dfs来解决
def dfs(grid, current_r, current_c, r, c):
count = 0
for i in range(r):
if grid[i][current_c] == 1:
# 使用改变列表的值来防止重复访问
grid[i][current_c] = 0
count += 1 + dfs(grid, i, current_c, r, c)
for i in range(c):
if grid[current_r][i] == 1:
# 使用改变列表的值来防止重复访问
grid[current_r][i] = 0
count += 1 + dfs(grid, current_r, i, r, c)
return count
res = 0
# 使用enumerate函数迭代可以找到对应的下标
# 通过下表进行访问
for r, row in enumerate(grid):
for c, col in enumerate(row):
if grid[r][c] == 1:
# 只有当n大于1了时候说明才是有第二个的服务器与之通信
n = dfs(grid, r, c, len(grid), len(grid[0]))
if n > 1:
# 只有能够与超过另外一台的服务器通信才可以计数
res += n
return res