1. 程式人生 > 其它 >【刷題刷題】省份數量

【刷題刷題】省份數量

技術標籤:bfsleetcode

547. 省份數量

難度中等471收藏分享切換為英文接收動態反饋

n個城市,其中一些彼此相連,另一些沒有相連。如果城市a與城市b直接相連,且城市b與城市c直接相連,那麼城市a與城市c間接相連。

省份是一組直接或間接相連的城市,組內不含其他沒有相連的城市。

給你一個n x n的矩陣isConnected,其中isConnected[i][j] = 1表示第i個城市和第j個城市直接相連,而isConnected[i][j] = 0表示二者不直接相連。

返回矩陣中省份的數量。

示例 1:

輸入:isConnected = [[1,1,0],[1,1,0],[0,0,1]]
輸出:
2

示例 2:

輸入:isConnected = [[1,0,0],[0,1,0],[0,0,1]]
輸出:3

提示:

  • 1 <= n <= 200
  • n == isConnected.length
  • n == isConnected[i].length
  • isConnected[i][j]10
  • isConnected[i][i] == 1
  • isConnected[i][j] == isConnected[j][i]

方法一:深度優先搜尋
深度優先搜尋的思路是很直觀的。遍歷所有城市,對於每個城市,如果該城市尚未被訪問過,則從該城市開始深度優先搜尋,通過矩陣 \textit{isConnected}isConnected 得到與該城市直接相連的城市有哪些,這些城市和該城市屬於同一個連通分量,然後對這些城市繼續深度優先搜尋,直到同一個連通分量的所有城市都被訪問到,即可得到一個省份。遍歷完全部城市以後,即可得到連通分量的總數,即省份的總數。

class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        def dfs(i: int):
            for j in range(provinces):
                if isConnected[i][j] == 1 and j not in visited:
                    visited.add(j)
                    dfs(j)
        
        provinces = len(isConnected)
        visited = set()
        circles = 0

        for i in range(provinces):
            if i not in visited:
                dfs(i)
                circles += 1
        
        return circles

方法二:廣度優先搜尋
也可以通過廣度優先搜尋的方法得到省份的總數。對於每個城市,如果該城市尚未被訪問過,則從該城市開始廣度優先搜尋,直到同一個連通分量中的所有城市都被訪問到,即可得到一個省份。

class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        provinces = len(isConnected)
        visited = set()
        circles = 0
        
        for i in range(provinces):
            if i not in visited:
                Q = collections.deque([i])
                while Q:
                    j = Q.popleft()
                    visited.add(j)
                    for k in range(provinces):
                        if isConnected[j][k] == 1 and k not in visited:
                            Q.append(k)
                circles += 1
        
        return circles