【LeetCode】547。県数(中)(JAVA)1日1問

【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つが接続されていないことを意味します。直接接続されています。

マトリックス内の州の数を返します。

問題解決方法

  1. 接続されているすべてのノードをセットに入れます
  2. 2つのノードの元のセットをマージします
  3. 最後に、残りのセットの数を見つけます
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%を上回っています

最適化

  1. セットの各要素を知る必要はなく、セットの数を計算するだけです。
  2. DFSを採用する(深さ優先探索)
  3. たとえば、位置i:1。isConnected [i] [i]を0に設定して、iがトラバースされたことを示します。2。接続がなくなるまでiに接続されているすべての位置をトラバースします。
  4. 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%を上回っています

私の公式アカウントに注意を払うことを歓迎します、LeetCodeは毎日1つの質問を更新します

おすすめ

転載: blog.csdn.net/qq_16927853/article/details/112302105