[路飞]_每天刷leetcode_41(省份的数量Number of provinces)

199 阅读2分钟

省份的数量(Number of provinces)

LeetCode传送门547.Number of Provinces

原题

有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。

返回矩阵中 省份 的数量。

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 ith city and the jth city are directly connected, and isConnected[i][j] = 0 otherwise.

Return the total number of provinces.

Example:


Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]]
Output: 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]

思考线


解题思路

并查集解法

首先这是一个连通性的问题,我们可以用并查集来解决问题。

不懂得如何使用并查集的同学,可以点击一下相关知识。

下面直接上代码

class UnionSets {
    n: number;
    fn: number[];
    isConnected: number[][]
    constructor(n: number, isConnected: number[][]) {
        this.n = n;
        this.fn = new Array(n).fill(0).map((item, index) => index);
        this.isConnected = isConnected;
        this.calculate();
    }
    find(ind: number) {
        if (this.fn[ind] === ind) return ind;
        this.fn[ind] = this.find(this.fn[ind]);
        return this.fn[ind];
    }
    merge(ind1, ind2) {
        this.fn[this.find(this.fn[ind1])] = this.find(this.fn[ind2]);
    }
    calculate() {
        for (let i = 0; i < this.n; i++) {
            for (let j = i + 1; j < this.n; j++) {
                if (this.isConnected[i][j] === 1) {
                    this.merge(i, j);
                }
            }
        }
    }
    counts() {
        let res = 0;
        for (let i = 0; i < this.n; i++) {
            if (this.fn[i] === i) res++;
        }
        return res;
    }
}
function findCircleNum(isConnected: number[][]): number {
    const set = new UnionSets(isConnected.length, isConnected);
    return set.counts()
}

利用图模型解法

关于连通性的问题我们也可以用图Graph模型来解决问题。

关于图 Graph的基础知识,请点击链接查阅。

对于创建的图模型的解题方案最常见的有深度优先搜索和广度优先搜索。

我们在这里使用广度优先策略。

function findCircleNum(isConnected: number[][]): number {

    const n = isConnected.length;
    const visited = {};
    const queue = [];
    let res = 0;
    for (let i = 0; i < n; i++) {
        if (!visited[i]) {
            queue.push(i);
            while (queue.length) {
                const q = queue.shift();
                for (let j = 0; j < n; j++) {
                    if (isConnected[q][j] === 1 && !visited[j]) {
                        queue.push(j);
                        visited[j] = Symbol()
                    }
                }
            }
            res ++;
        }
    }
    return res;
}

这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。