【刷题算法】寻找岛的个数

昨晚听左神讲了一个很有意思的题。题目意思大概是:

给定一个二维数组,所有位置的值不是0就是1。规定每个位置可以和它上下左右位置上的值相连。有一个叫做岛的概念,定义如下:
连成一片的1,如果周围都是0,那么这一片1,构成一个岛。

求整张图上有多少个岛。

例如:
0 0 0 0 0 0 0 0 0
0 1 1 0 0 1 1 1 0
0 1 1 1 0 0 0 1 0
0 1 1 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0
0 0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0
这张图上有三个岛。

0 0 0 0 0 0 0 0 0
0 1 1 0 1 1 1 1 0
0 1 1 1 1 0 0 1 0
0 1 1 0 0 0 0 1 0
0 0 0 0 0 1 1 1 0
0 0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0
这张图上有一个岛。

遇到这种题目,我的第一反应就是针对二维数组中的元素进行逐次用BFS或DFS进行遍历,如果遇到边界或值为0的时候,就停下来,统计BFS或DFS的遍历次数即可

然而左神给了与BFS差不多的思路,然而在整体实现上比BFS简单的多
比如说,如果登岛的时候(当第一次遇见值为1的时候),就对周边的1进行感染,那么这个岛就会被一次感染完。如果遇到其他岛屿的话,如上操作。那么我们可以根据几次感染的次数对岛屿的个数进行估计

void infect(int *arr, int i, int j, int w, int h) {

    if (i < 0 || i >= h || j < 0 || j >= w || arr[i*w + j] != 1)
        return;
    arr[i*w+j] = 2;
    infect(arr, i - 1, j, w, h);
    infect(arr, i + 1, j, w, h);
    infect(arr, i, j - 1, w, h);
    infect(arr, i, j + 1, w, h);
}


int calcIsland(int *arr, int w, int h) {

    int res = 0;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (arr[i*w + j] == 1) {
                res++;
                infect(arr, i, j, w, h);
            }
        }
    }
    return res;

}

你可能感兴趣的:(刷题算法)