整体思路

  1. 在输入的图中,首先选取一个可以走的点。(是陆地,且没有被访问过)
  2. 然后根据这一个点,使用BFS或者DFS向四周去扩张,把所有能扩张的全访问一遍
  3. 最终,最上层找到几个能访问的点,就是几个独立岛屿
  4. 这个题目说白了就是图的寻找连通块一样

    题目细节

  • 使用方向数组表示行进方向
  • 上 左,下,右
  • dx = {-1, 0, 0, 1}
  • dy = {0, -1, 1, 0}
  1. class Solution {
  2. //记录一下子输入数据,省着下传了
  3. private char[][] grid;
  4. //记录一下子行数和列数,作为共享变量
  5. int rowNum;
  6. int colNum;
  7. //创建一个和输入一样大小的二维数组,以此记录一个点是否被访问过
  8. boolean[][] vistied;
  9. public int numIslands(char[][] grid) {
  10. this.grid = grid;
  11. this.rowNum = grid.length;
  12. this.colNum = grid[0].length;
  13. vistied = new boolean[rowNum][colNum];
  14. //答案
  15. int ans = 0;
  16. //遍历整个输入的二维数组,选取一个没有被访问过的且为1的点,然后使用bfs去四周扩张,只到把可访问的点全部扩张完成且访问
  17. for(int i = 0;i < rowNum;i++){
  18. for(int j = 0;j < colNum;j++){
  19. if(grid[i][j] == '1' && !vistied[i][j]){
  20. //答案+1 找到一个没有被访问的过岛屿,答案就加一。这是因为下面bfs会把找到的每一个岛屿全访问完的
  21. //所以只要找到的岛屿,就是新的岛屿
  22. ans++;
  23. bfs(i,j);
  24. }
  25. }
  26. }
  27. return ans;
  28. }
  29. public void bfs(int x,int y){
  30. //只要是广度优先遍历,就先把队列拿出来
  31. Queue<Pair<Integer,Integer>> queue = new LinkedList<>();
  32. //方向数组(记录行进方向的值),也就是x y + 方向数组的值 = 下一个点的坐标
  33. // 上, 左, 右,下
  34. int[] dx = new int[]{-1, 0, 0, 1};
  35. int[] dy = new int[]{0, -1, 1, 0};
  36. //把当前点放入队列中去
  37. queue.add(new Pair<>(x,y));
  38. while (!queue.isEmpty()){
  39. //1:队头出队,记录当前点
  40. Pair<Integer, Integer> point = queue.poll();
  41. int nowX = point.getKey();
  42. int nowY = point.getValue();
  43. //记录这个点已经被访问过了
  44. vistied[nowX][nowY] = true;
  45. //2:以当前点为圆心,想上下左右扩张,能走的地方就标记访问
  46. for(int i = 0;i < 4; i++){
  47. //获取到当前点的下一个方向的点的坐标
  48. int nextX = nowX + dx[i];
  49. int nextY = nowY + dy[i];
  50. //如果新的点超过边界了,就忽略这个点
  51. if(nextX < 0 || nextX >= rowNum || nextY < 0 || nextY >= colNum){
  52. continue;
  53. }
  54. //如果新的点不是岛屿则忽略这给点
  55. if(grid[nextX][nextY] != '1'){
  56. continue;
  57. }
  58. //如果新的点已经被访问过了则忽略这个点
  59. if(vistied[nextX][nextY]){
  60. continue;
  61. }
  62. //如果上面条件都不满足,说明是新点是一个没被访问的合法的陆地,那么就把这个点入队让他继续扩张去,然后记录已访问
  63. queue.add(new Pair<>(nextX,nextY));
  64. vistied[nextX][nextY] = true;
  65. }
  66. }
  67. }
  68. }