547. Number of Provinces

Photo by Siegfried Poepperl on Unsplash
Photo by Siegfried Poepperl on Unsplash
解這題的想法是,將所有相連的點分成一群。第一個想到方法是,我們可以利用 Union Find 來將點做分群。

Problem

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.

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 ith city and the jth 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]

Solution

解這題的想法是,將相連的點分成一群。

第一個想到方法是,我們可以利用 Union Find 來將點做分群。

第二個想到的方法是,對於任一個點,我們可以用 DFS 或 BFS 來所有找出相連的點,而這些點就會成一個群。然後,再對任一還沒被分群的點,做上述的動作,一直到所有的點都被分群。

Union Find

  • Time: O(n^2)
  • Space: O(n)
class Solution {
    class UnionFind {
        private int[] parents;
        private int count;

        UnionFind(int size) {
            count = size;
            parents = new int[size];
            for (int i = 0; i < size; i++) {
                parents[i] = i;
            }
        }

        int find(int x) {
            while (x != parents[x]) {
                x = parents[x];
                parents[x] = parents[parents[x]];
            }
            return x;
        }

        void union(int x, int y) {
            int parentX = find(x);
            int parentY = find(y);
            if (parentX == parentY) {
                return;
            } else if (parentX < parentY) {
                parents[parentY] = parentX;
            } else {
                parents[parentX] = parentY;
            }
            count--;
        }

        int getCount() {
            return count;
        }
    }

    public int findCircleNum(int[][] isConnected) {
        int n = isConnected.length;
        UnionFind uf = new UnionFind(n);
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                if (i == j) continue;
                if (isConnected[i][j] == 1) {
                    uf.union(i, j);
                }
            }
        }
        return uf.getCount();
    }
}

DFS

  • Time: O(n^2)
  • Space: O(n)
class Solution {
    public int findCircleNum(int[][] isConnected) {
        int count = 0;
        boolean[] isVisited = new boolean[isConnected.length];
        for (int i = 0; i < isConnected.length; i++) {
            if (!isVisited[i]) {
                dfs(isConnected, i, isVisited);
                count++;
            }

        }
        return count;
    }

    private void dfs(int[][] isConnected, int i, boolean[] isVisited) {
        isVisited[i] = true;
        for (int j = 0; j < isConnected.length; j++) {
            if (isConnected[i][j] == 1 && !isVisited[j]) {
                dfs(isConnected, j, isVisited);
            }
        }
    }
}

BFS

  • Time: O(n^2)
  • Space: O(n)
class Solution {
    public int findCircleNum(int[][] isConnected) {
        int count = 0;
        boolean[] isVisited = new boolean[isConnected.length];
        for (int i = 0; i < isConnected.length; i++) {
            if (!isVisited[i]) {
                bfs(isConnected, i, isVisited);
                count++;
            }

        }
        return count;
    }

    private void bfs(int[][] isConnected, int i, boolean[] isVisited) {
        Queue<Integer> queue = new ArrayDeque<>();
        queue.offer(i);
        while (!queue.isEmpty()) {
            int v = queue.poll();
            if (isVisited[v]) continue;
            isVisited[v] = true;
            for (int j = 0; j < isConnected.length; j++) {
                if (isConnected[v][j] == 1 && !isVisited[j]) {
                    queue.offer(j);
                }
            }
        }
    }
}

參考

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

You May Also Like
Photo by Oladimeji Odunsi on Unsplash
Read More

72. Edit Distance

在解此題時,我們要先觀察 word1 如何變成 word2。以 Example1 為例,左下圖列出 “horse” 轉變成 “ros” 的 distance。表中,縱軸表示 “horse”,而橫軸表示 “ros”。
Read More
Photo by Diana Parkhouse on Unsplash
Read More

1048. Longest String Chain

此題中,wordA 是 wordB 的 predecessor 指只要插入一個 letter 到 wordA,那就會使得它和 wordB 一樣。然而,插入一個 letter 到一個地方,就要考慮 26 種字母。這使得整體的複雜度上升。
Read More
Photo by Bogdan Farca on Unsplash
Read More

39. Combination Sum

此題要我們列出所有可能的組合,所以我們可能用 backtracking 來找。但是,我們必須避免找到相同的組合。當兩個組合裡的數字和個數都依一樣,但順序不一樣時,他們依然是相同的組合。
Read More