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