Leetcode—200.Number of Islands

来源:互联网 发布:教务系统数据库设计 编辑:程序博客网 时间:2024/05/17 19:19

问题描述:

Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

11110
11010
11000
00000

Answer: 1

Example 2:

11000
11000
00100
00011

Answer: 3

问题概括,如果0代表水,1代表陆地,连在一起的表示一块陆地,那么整个二维数组被划分成了几块陆地?


解题思路:

考察数据集合划分几个子集的问题,首先能想到的就是并查集。并查集在划分元素集合,查找元素所在集合以及子集合合并上都有很不错的效率。

具体到这个问题,我们首先将二维的数据映射到一维的并查集数组,然后遍历数据。我们是从右下角开始遍历的,因为二维数据中有元素的值为 ‘0’,我们把它并查集值设置为0,如果从左上开始遍历,因为第一个元素为0,可能会让某子集合元素的值(根节点)为0,不是很方便。

对遍历的每个元素,如果当前元素为 ' 1 ' ,说明是陆地,我们得找找他有没有连在一起的陆地,寻找相邻节点,这里是下方以及右方(如果是左上开始遍历就是上方和左边)的元素(如果存在的话),寻找这两个相邻节点所属的集合,

1.如果他们陆地(‘1’)并且属于同一个集合,那么将当前元素也归到这个集合;

2.如果他们是陆地并且不属于同一个集合,那么将他们合并到同一个集合,此时集合数量-1;

3.如果其中一个是陆地,那么直接将当前节点归到相邻节点所属的集合;

4.如果相邻节点没有陆地,就让他自成一个集合,此时集合数量+1。

关于并查集的详细知识自行百度~

下面给出源代码:

class Solution {public:    int find(int k, vector<int>& u){        return k == u[k] ? k : u[k] = find(u[k],u);    }    int numIslands(vector<vector<char>>& grid) {        int res = 0;        int m = grid.size();        if (!m) return 0;        int n = grid[0].size();        if (!n) return 0;        vector<int>us(grid.size()*grid[0].size());        //从右下角开始遍历        for (int i = m - 1; i >= 0; i--)            for (int j = n - 1; j >= 0; j--){                if (grid[i][j] != '0'){                    int k = i*n + j;                    //并查集                    int s = i != m - 1 && grid[i+1][j] != '0' ? find(k + n, us) : 0;                    int t = j != n - 1 && grid[i][j+1] != '0' ? find(k + 1, us) : 0;                    if (s == t){                        if (s) us[k] = s;                        else { us[k] = k; res++; }                    }                    else{                        if (!s) us[k] = t;                        else if (!t) us[k] = s;                        else{ us[k] = us[s] = us[t] = max(us[s], us[t]); res--; }                    }                }            }        return res;    }   };

此外,还可以使用DFS的方法进行寻找,从左上到右下角进行遍历,每次找到一个1,说明有一个岛屿,采用DFS把他所有相邻的1全部置为0。便利一遍后就得到岛屿数量。


原创粉丝点击