ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

292,岛屿数量

2021-06-14 23:02:14  阅读:159  来源: 互联网

标签:queue return int 岛屿 DFSMarking char grid 292 数量


给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

输入:
11110
11010
11000
00000

输出: 1

示例 2:

输入:
11000
11000
00100
00011

输出: 3

答案:

 1public int numIslands(char[][] grid) {
2    int count = 0;
3    if (grid.length == 0)
4        return 0;
5    for (int i = 0; i < grid.length; i++) {
6        for (int j = 0; j < grid[0].length; j++)
7            if (grid[i][j] == '1') {
8                DFSMarking(grid, i, j);
9                ++count;
10            }
11    }
12    return count;
13}
14
15private void DFSMarking(char[][] grid, int i, int j) {
16    if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] != '1')
17        return;
18    grid[i][j] = '0';
19    DFSMarking(grid, i + 1, j);
20    DFSMarking(grid, i - 1, j);
21    DFSMarking(grid, i, j + 1);
22    DFSMarking(grid, i, j - 1);
23}

解析:

题目说了,网格的四边都被水包围,所以网格中只要不全是0,就肯定有岛屿,这里岛屿的定义是他的上下左右都是水。代码中第7行,如果当前网格是1,就会调用DFSMarking,DFSMarking使用递归的方法,然后再遍历他的右左下上四个方向,原理比较简单,下面再来看种解法

 1static int[] dx = {-1, 0, 0, 1};
2static int[] dy = {0, 1, -1, 0};
3
4public static int numIslands(char[][] grid) {
5    if (grid == null || grid.length == 0)
6        return 0;
7    int islands = 0;
8    for (int i = 0; i < grid.length; i++) {
9        for (int j = 0; j < grid[i].length; j++) {
10            if (grid[i][j] == '1') {
11                explore(grid, i, j);
12                islands++;
13            }
14        }
15    }
16    return islands;
17}
18
19public static void explore(char[][] grid, int i, int j) {
20    grid[i][j] = '0';
21    for (int d = 0; d < dx.length; d++) {
22        if (i + dy[d] < grid.length && i + dy[d] >= 0 && j + dx[d] < grid[0].length && j + dx[d] >= 0 && grid[i + dy[d]][j + dx[d]] == '1') {
23            explore(grid, i + dy[d], j + dx[d]);
24        }
25    }
26}

上面两种写法的本质并没有变,原理还都是一样的。就是找到一个为1的网格,然后再递归的方式遍历他的上下左右四个方向,注意递归的时候这两种方法都会有一些边界的判断。或者还可以再换一种解法

 1public int numIslands(char[][] grid) {
2    int islands = 0;
3    for (int i = 0; i < grid.length; i++)
4        for (int j = 0; j < grid[i].length; j++)
5            islands += sink(grid, i, j);
6    return islands;
7}
8
9int[] d = {0, 1, 0, -1, 0};
10
11int sink(char[][] grid, int i, int j) {
12    if (i < 0 || i == grid.length || j < 0 || j == grid[i].length || grid[i][j] == '0')
13        return 0;
14    grid[i][j] = '0';
15    for (int k = 0; k < 4; k++)
16        sink(grid, i + d[k], j + d[k + 1]);
17    return 1;
18}

我们再来看一个不使用递归解法的方式

 1public int numIslands(char[][] grid) {
2    int count = 0;
3    for (int i = 0; i < grid.length; i++)
4        for (int j = 0; j < grid[0].length; j++) {
5            if (grid[i][j] == '1') {
6                bfsFill(grid, i, j);
7                count++;
8            }
9        }
10    return count;
11}
12
13private void bfsFill(char[][] grid, int x, int y) {
14    grid[x][y] = '0';
15    int n = grid.length;
16    int m = grid[0].length;
17    LinkedList<Integer> queue = new LinkedList<>();
18    int code = x * m + y;
19    queue.offer(code);
20    while (!queue.isEmpty()) {
21        code = queue.poll();
22        int i = code / m;
23        int j = code % m;
24        if (i > 0 && grid[i - 1][j] == '1')    //上
25        {
26            queue.offer((i - 1) * m + j);
27            grid[i - 1][j] = '0';
28        }
29        if (i < n - 1 && grid[i + 1][j] == '1')  //下
30        {
31            queue.offer((i + 1) * m + j);
32            grid[i + 1][j] = '0';
33        }
34        if (j > 0 && grid[i][j - 1] == '1')  //左
35        {
36            queue.offer(i * m + j - 1);
37            grid[i][j - 1] = '0';
38        }
39        if (j < m - 1 && grid[i][j + 1] == '1')  //右
40        {
41            queue.offer(i * m + j + 1);
42            grid[i][j + 1] = '0';
43        }
44    }
45}

这里的code其实相当于把二维数组转化为了一维数组来存储,代码不难理解,比较难理解的估计就是一些计算,while循环中的i相当于二维数组的第几行,j相当于二维数组的第几列。其他的就没什么了,也是和上面其他几种解法一样,遍历他的上下左右网格。

标签:queue,return,int,岛屿,DFSMarking,char,grid,292,数量
来源: https://blog.51cto.com/u_4774266/2902574

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有