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; }
相关文章推荐
- Entity Fr“.NET技术”amework 4.1 Code First 学习之路(二)
- Entity Fram“.NET研究”ework 4.1 Code First 学习之路(二)
- lintcode---滑动窗口内唯一元素数量和 (Sliding Window Unique Elements Sum)
- Entity Framework 4.1 Code First 学习之路
- Entity Framework 4.1 Code First 学习之路(一)
- Entity Framework 4.1 Code First 学习之路(二)
- 一起谈.NET技术,Entity Framework 4.1 Code First 学习之路(二)
- 坐标系统 Qt 学习之路 2(28):坐标系统
- ExtJS学习之路第六步:深入讨论组件Panel用法
- LintCode "Previous Permutation"
- HTML5学习之路--js动态添加svg节点
- Lintcode--009(单词切分)
- lintcode-逆波兰表达式求值-424
- Hive学习笔记 --- return code 1 from org.apache.hadoop.hive
- PHP学习之路(二)——WampSever
- lintcode求两个数组的交出错
- LintCode : Binary Tree Path Sum
- python 包pandas的学习之路(-)
- IOS 学习之路(一) 徒手写界面(2)自适应和懒加载
- Struts2的学习之路(四)