【LeetCode】547。都道府県数(中)(JAVA)
件名アドレス:https://leetcode.com/problems/number-of-provinces/
タイトル説明:
nの都市があります。接続されているものと接続されていないものがあります。都市aが都市bに直接接続され、都市bが都市cに直接接続されている場合、都市aは都市cに間接的に接続されます。
州は、直接的または間接的に接続された都市のグループであり、グループ外の他の都市はありません。
i番目の都市とj番目の都市が直接接続されている場合はisConnected [i] [j] = 1、それ以外の場合はisConnected [i] [j] = 0のnxn行列isConnectedが与えられます。
州の総数を返します。
例1:
Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]]
Output: 2
例2:
Input: isConnected = [[1,0,0],[0,1,0],[0,0,1]]
Output: 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]
一般的なアイデア
nの都市があり、それらのいくつかは互いに接続されており、いくつかは接続されていません。都市aと都市bが直接接続されており、都市bが都市cに直接接続されている場合、都市aと都市cは間接的に接続されます。
州は、直接または間接的に接続された都市のグループであり、グループには他の接続されていない都市は含まれません。
nxn行列isConnectedを与えます。ここで、isConnected [i] [j] = 1は、i番目の都市とj番目の都市が直接接続されていることを意味し、isConnected [i] [j] = 0は、2つが接続されていないことを意味します。直接接続されています。
マトリックス内の州の数を返します。
問題解決方法
- 接続されているすべてのノードをセットに入れます
- 2つのノードの元のセットをマージします
- 最後に、残りのセットの数を見つけます
class Solution {
public int findCircleNum(int[][] isConnected) {
List<Set<Integer>> list = new ArrayList<>();
for (int i = 0; i < isConnected.length; i++) {
for (int j = 0; j < isConnected[0].length; j++) {
if (isConnected[i][j] == 0) continue;
merge(list, i, j);
}
}
return list.size();
}
public void merge(List<Set<Integer>> list, int num1, int num2) {
Set<Integer> set1 = getPre(list, num1);
Set<Integer> set2 = getPre(list, num2);
if (set1 == null && set2 == null) {
Set<Integer> temp = new HashSet<>();
temp.add(num1);
temp.add(num2);
list.add(temp);
} else if (set1 == null) {
set2.add(num1);
list.add(set2);
} else if (set2 == null) {
set1.add(num2);
list.add(set1);
} else {
set1.addAll(set2);
list.add(set1);
}
}
public Set<Integer> getPre(List<Set<Integer>> list, int num) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).contains(num)) return list.remove(i);
}
return null;
}
}
実行時間:6ミリ秒、Javaユーザーの20.20%を上回っています
メモリ消費量:39.7 MB、Javaユーザーの17.42%を上回っています
最適化
- セットの各要素を知る必要はなく、セットの数を計算するだけです。
- DFSを採用する(深さ優先探索)
- たとえば、位置i:1。isConnected [i] [i]を0に設定して、iがトラバースされたことを示します。2。接続がなくなるまでiに接続されているすべての位置をトラバースします。
- isConnected [i] [i] == 1のたびに、前のすべてのi-1ノードがノードiに接続されておらず、すべてが独立したセットであることを意味します
class Solution {
public int findCircleNum(int[][] isConnected) {
int res = 0;
for (int i = 0; i < isConnected.length; i++) {
if (isConnected[i][i] == 0) continue;
fH(isConnected, i);
res++;
}
return res;
}
public void fH(int[][] isConnected, int index) {
if (isConnected[index][index] == 0) return;
isConnected[index][index] = 0;
for (int i = 0; i < isConnected.length; i++) {
if (isConnected[index][i] == 0) continue;
fH(isConnected, i);
}
}
}
実行時間:1ミリ秒、Javaユーザーの99.49%を上回っています
メモリ消費量:39.6 MB、Javaユーザーの30.21%を上回っています