您的位置:首页 > 其它

lintCode学习之路:大岛的数量

2017-12-25 18:28 134 查看

大岛的数量

给一个布尔类型的二维数组, 0 表示海, 1 表示岛。如果两个1是相邻的,那么我们认为他们是同一个岛.我们只考虑 上下左右 相邻.

找到大小在 k 及 k 以上的岛屿的数量

样例

给一个二维数组:

[

[1, 1, 0, 0, 0],

[0, 1, 0, 0, 1],

[0, 0, 0, 1, 1],

[0, 0, 0, 0, 0],

[0, 0, 0, 0, 1]

]

给出 K = 2

返回 2

解题思路:

题目的含义其实很简单,就是求boolean矩阵中连通的区域,解此题的方式可以使用计算机图形学中的种子填充算法,题目要求是上下左右,所以采用四向联通算法,算法如下:

1.顺序遍历数组,取一个有效点作为填充起点

2.对起点的上下左右进行判断

3.取其中的有效点重复2操作,直至没有有效点

重复123

整个数组执行完之后每次的填充的轨迹就构成一个岛,统计这些岛的数量就可以计算出所有大岛数量

代码如下:

static int color = 0;
static Map<Integer, Integer> islandSize = new HashMap<>();

public static int numsofIsland(boolean[][] grid, int k) {
int len = grid.length;
if(len==0){
return 0;
}
if(len==1){
return 0;
}
int islandNum = 0;
Map<String, Integer> map = new HashMap<>();
for(int i = 0; i < len; i ++){
for(int j = 0; j < grid[i].length; j ++){
if(!grid[i][j]||map.containsKey(i + "," + j)){
continue;
}
color++;
islandSize.put(color, 0);
boundaryFill4(grid, map, i, j);
}
}
for(int i = color; i > 0; i--){
if(islandSize.get(i)>=k){
islandNum++;
}
}
return islandNum;
}

public static void boundaryFill4(boolean[][] grid, Map<String, Integer> map, int i, int j){
map.put(i + "," + j, 1);
islandSize.put(color, islandSize.get(color)+1);
if(i<(grid.length-1)&&grid[i+1][j]&&!map.containsKey((i+1) + "," + j)){
boundaryFill4(grid, map, i+1, j);
}

if(i>0&&grid[i-1][j]&&!map.containsKey((i-1) + "," + j)){
boundaryFill4(grid, map, i-1, j);
}

if(j<(grid[i].length-1)&&grid[i][j+1]&&!map.containsKey(i + "," + (j+1))){
boundaryFill4(grid, map, i, j+1);
}

if(j>0&&grid[i][j-1]&&!map.containsKey(i + "," + (j-1))){
boundaryFill4(grid, map, i, j-1);
}
}


从代码可以看出,算法采用了迭代,因此在大量数据输入的情况下算法会出现堆栈溢出,本着AC万岁的原则我还是提交了,果不其然溢出了,没办法,只能将算法迭代实现改成while循环,采用队列存储走过的连通区域,改进后的算法总算能AC了

代码如下

public static int numsofIsland2(boolean[][] grid, int k) {
int len = grid.length;
if(len==0){
return 0;
}
if(len==1){
return 0;
}
int islandNum = 0;
Map<String, Integer> map = new HashMap<>();
Queue<String> queue = new LinkedList<String>();
for(int i = 0; i < len; i ++){
for(int j = 0; j < grid[i].length; j ++){
if(!grid[i][j]||map.containsKey(i + "," + j)){
continue;
}
queue.add(i + "," + j);
map.put(i + "," + j, 1);
int tmp = 0;
while(queue.size()!=0){
String site = queue.poll();
int m = Integer.parseInt(site.split(",")[0]);
int n = Integer.parseInt(site.split(",")[1]);
tmp++;
if(m<(grid.length-1)&&grid[m+1]
&&!map.containsKey((m+1) + "," + n)){
queue.add((m+1) + "," + n);
map.put((m+1) + "," + n, 1);
}

if(m>0&&grid[m-1]
&&!map.containsKey((m-1) + "," + n)){
queue.add((m-1) + "," + n);
map.put((m-1) + "," + n, 1);
}

if(n<(grid[m].length-1)&&grid[m][n+1]&&!map.containsKey(m + "," + (n+1))){
queue.add(m + "," + (n+1));
map.put(m + "," + (n+1), 1);
}

if(n>0&&grid[m][n-1]&&!map.containsKey(m + "," + (n-1))){
queue.add(m + "," + (n-1));
map.put(m + "," + (n-1), 1);
}
}
if(tmp>=k){
islandNum++;
}
}
}
return islandNum;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  种子填充算法