【LeetCode】547. Number of Provinces (Medium) (JAVA) One question per day

【LeetCode】547. Number of Provinces (Medium) (JAVA)

Subject address: https://leetcode.com/problems/number-of-provinces/

Title description:

There are n cities. Some of them are connected, while some are not. If city a is connected directly with city b, and city b is connected directly with city c, then city a is connected indirectly with city c.

A province is a group of directly or indirectly connected cities and no other cities outside of the group.

You are given an n x n matrix isConnected where isConnected[i][j] = 1 if the i-th city and the j-th city are directly connected, and isConnected[i][j] = 0 otherwise.

Return the total number of provinces.

Example 1:

Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]]
Output: 2

Example 2:

Input: isConnected = [[1,0,0],[0,1,0],[0,0,1]]
Output: 3

Constraints:

  • 1 <= n <= 200
  • n == isConnected.length
  • n == isConnected[i].length
  • isConnected[i][j] is 1 or 0.
  • isConnected[i][i] == 1
  • isConnected[i][j] == isConnected[j][i]

General idea

There are n cities, some of which are connected to each other, and some of them are not connected. If city a and city b are directly connected, and city b is directly connected to city c, then city a and city c are indirectly connected.

A province is a group of directly or indirectly connected cities, and the group does not contain other unconnected cities.

Give you an nxn matrix isConnected, where isConnected[i][j] = 1 means that the i-th city and the j-th city are directly connected, and isConnected[i][j] = 0 means that the two are not directly connected.

Returns the number of provinces in the matrix.

Problem-solving method

  1. Put all connected nodes into a set
  2. Merge the original set of the two nodes
  3. Finally, find the number of remaining sets
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;
    }
}

Execution time: 6 ms, beating 20.20% of Java users
Memory consumption: 39.7 MB, beating 17.42% of Java users

optimization

  1. There is no need to know each element of the set, just calculate the number of sets.
  2. Adopt DFS (depth first search)
  3. For example, position i: 1. Set isConnected[i][i] to 0 to indicate that i has been traversed; 2. Traverse all positions connected to i until there is no connection
  4. Every time isConnected[i][i] == 1 means that all i-1 nodes in front are not connected to node i, all are an independent set
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);
        }
    }
}

Execution time: 1 ms, beating 99.49% of Java users
Memory consumption: 39.6 MB, beating 30.21% of Java users

Welcome to pay attention to my official account, LeetCode updates one question every day

Guess you like

Origin blog.csdn.net/qq_16927853/article/details/112302105