1. 程式人生 > 其它 >【LeetCode】每日一題547. 省份數量

【LeetCode】每日一題547. 省份數量

技術標籤:每日一題dfs演算法圖論leetcodejava

547. 省份數量

有 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] 為 1 或 0
  • isConnected[i][i] == 1
  • isConnected[i][j] == isConnected[j][i]

方法一:並查集

  • 昨天才被並查集虐了,今天又來~。
  • 不過這題並查集並不是最優解,用並查集解題練練思路
public int findCircleNum
(int[][] isConnected) { int n = isConnected.length; int[] parent = new int[n]; for (int i = 0; i < n; i++) { parent[i] = i; } for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (isConnected[i][j] == 1) { union(parent,
i, j); } } } int ret = 0; for (int i = 0; i < n; i++) { if (parent[i] == i) { ret++; } } return ret; } public void union(int[] parent, int p, int q) { parent[find(parent, p)] = find(parent, q); } public int find(int[] parent, int i) { if (parent[i] != i) { parent[i] = find(parent, parent[i]); } return parent[i]; }

方法二:DFS

深度優先搜尋 和 廣度優先搜尋 都能解決。時間複雜度為 O(n2),比並查集低。

// 深度優先搜尋
public int findCircleNum(int[][] isConnected) {
    int n = isConnected.length;
    boolean[] visited = new boolean[n];
    int ret = 0;
    for (int i = 0; i < n; i++) {
        if (!visited[i]) {
            dfs(i, visited, isConnected);
            ret++;
        }
    }
    return ret;
}
public void dfs(int i, boolean[] visited, int[][] isConnected){
    for (int j = 0; j < isConnected.length; j++) {
        if (isConnected[i][j] == 1 && !visited[j]) {
            visited[j] = true;
            dfs(j, visited, isConnected);
        }
    }
}

執行結果

在這裡插入圖片描述