资讯专栏INFORMATION COLUMN

[Leetcode] Number of Islands 岛屿个数

Raaabbit / 2443人阅读

摘要:同时我们每找到一个,就将其标为,这样就能把整个岛屿变成。我们只要记录对矩阵遍历时能进入多少次搜索,就代表有多少个岛屿。

Number of Islands 最新更新的思路,以及题II的解法请访问:https://yanjia.me/zh/2018/11/...

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

标零法 复杂度

时间 O(NM) 空间 O(max(N,M)) 递归栈空间

思路

我们遍历矩阵的每一个点,对每个点都尝试进行一次深度优先搜索,如果搜索到1,就继续向它的四周搜索。同时我们每找到一个1,就将其标为0,这样就能把整个岛屿变成0。我们只要记录对矩阵遍历时能进入多少次搜索,就代表有多少个岛屿。

代码
public class Solution {
    public int numIslands(char[][] grid) {
        int res = 0;
        if(grid.length==0) return res;
        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid[0].length; j++){
                if(grid[i][j]=="1"){
                    searchIsland(grid, i, j);
                    res++;
                }
            }
        }
        return res;
    }
    
    private void searchIsland(char[][] grid, int i, int j){
        grid[i][j]="0";
        // 搜索该点连通的上下左右
        if(i>0 && grid[i-1][j]=="1") searchIsland(grid, i-1, j);
        if(j>0 && grid[i][j-1]=="1") searchIsland(grid, i, j-1);
        if(i

2018/2

class Solution:
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        count = 0
        for row in range(0, len(grid)):
            for col in range(0, len(grid[0])):
                if grid[row][col] == "1":
                    self.exploreIsland(grid, row, col)
                    count += 1
        return count
                    
    
    def exploreIsland(self, grid, row, col):
        grid[row][col] = "0"
        if (row > 0 and grid[row - 1][col] == "1"):
            self.exploreIsland(grid, row - 1, col)
        if (col > 0 and grid[row][col - 1] == "1"):
            self.exploreIsland(grid, row, col - 1)
        if (row < len(grid) - 1 and grid[row + 1][col] == "1"):
            self.exploreIsland(grid, row + 1, col)
        if (col < len(grid[0]) - 1 and grid[row][col + 1] == "1"):
            self.exploreIsland(grid, row, col + 1)

2018/10

func explore(grid *[][]byte, row int, col int) {
    (*grid)[row][col] = "0"
    if row > 0 && (*grid)[row-1][col] == "1" {
        explore(grid, row-1, col)
    }
    if row < len((*grid))-1 && (*grid)[row+1][col] == "1" {
        explore(grid, row+1, col)
    }
    if col > 0 && (*grid)[row][col-1] == "1" {
        explore(grid, row, col-1)
    }
    if col < len((*grid)[0])-1 && (*grid)[row][col+1] == "1" {
        explore(grid, row, col+1)
    }
}

func numIslands(grid [][]byte) int {
    count := 0
    for i, row := range grid {
        for j, val := range row {
            if val == "1" {
                explore(&grid, i, j)
                count++
            }
        }

    }
    return count
}
后续 Follow Up

Q:如何找湖的数量呢?湖的定义是某个0,其上下左右都是同一个岛屿的陆地。
A:我们可以先用Number of island的方法,把每个岛标记成不同的ID,然后过一遍整个地图的每个点,如果是0的话,就DFS看这块连通水域是否被同一块岛屿包围,如果出现了不同数字的陆地,则不是湖。

public class NumberOfLakes {
    
    public static void main(String[] args){
        NumberOfLakes nof = new NumberOfLakes();
        int[][] world = {{1,1,1,0,1},{1,0,0,1,0},{1,1,1,1,1,},{0,1,1,0,1},{0,1,1,1,1}};
        System.out.println(nof.numberOfLakes(world));
    }
    
    public int numberOfLakes(int[][] world){
        int islandId = 2;
        for(int i = 0; i < world.length; i++){
            for(int j = 0; j < world[0].length; j++){
                if(world[i][j] == 1){
                    findIsland(world, i, j, islandId);
                    islandId++;
                }
            }
        }
        int lake = 0;
        for(int i = 0; i < world.length; i++){
            for(int j = 0; j < world[0].length; j++){
                if(world[i][j] == 0){
                    // 找到当前水域的邻接陆地编号
                    int currId = 0;
                    if(i > 0) currId = (world[i - 1][j] != 0 ? world[i - 1][j] : currId);
                    if(j > 0) currId = (world[i][j - 1] != 0 ? world[i][j - 1] : currId);
                    if(i < world.length - 1) currId = (world[i + 1][j] != 0 ? world[i + 1][j] : currId);
                    if(j < world[0].length - 1) currId = (world[i][j + 1] != 0 ? world[i][j + 1] : currId);
                    // 如果该点是湖,加1
                    if(findLake(world, i, j, currId)){
                        lake++;
                    }
                }
            }
        }
        return lake;
    }
    
    private boolean findLake(int[][] world, int i, int j, int id){
        // 将当前水域标记成周边岛屿的数字
        world[i][j] = id;
        // 找上下左右是否是同一块岛屿的陆地,如果是水域则继续DFS,如果当前水域是边界也说明不是湖
        boolean up = i != 0 
                && (world[i - 1][j] == id 
                || (world[i - 1][j] == 0 && findLake(world, i - 1, j, id)));
        boolean down = i != world.length - 1 
                && (world[i + 1][j] == id 
                || (world[i + 1][j] == 0 && findLake(world, i + 1, j, id)));
        boolean left = j != 0 
                && (world[i][j - 1] == id 
                || (world[i][j - 1] == 0 && findLake(world, i, j - 1, id)));
        boolean right = j != world[0].length - 1 
                && (world[i][j + 1] == id 
                || (world[i][j + 1] == 0 && findLake(world, i, j + 1, id)));
        return up && down && right && left;
    }
    
    private void findIsland(int[][] world, int i, int j, int id){
        world[i][j] = id;
        if(i > 0 && world[i - 1][j] == 1) findIsland(world, i - 1, j, id);
        if(j > 0 && world[i][j - 1] == 1) findIsland(world, i, j - 1, id);
        if(i < world.length - 1 && world[i + 1][j] == 1) findIsland(world, i + 1, j, id);
        if(j < world[0].length - 1 && world[i][j + 1] == 1) findIsland(world, i, j + 1, id);
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64546.html

相关文章

  • [Leetcode] Number of Islands 岛屿数量(JavaScript 实现)

    摘要:解题思路标零法对这个矩阵进行循环访问每一个点当这个点等于,岛屿数量,与其同时用算法访问周围的其他点,进行同样的操作且将访问过且等于的点标记为零。版本岛屿数量搜索右边搜索左边搜索下边搜索上边 Q: Number of Islands Given a 2d grid map of 1s (land) and 0s (water), count the number of islands. ...

    pingan8787 评论0 收藏0
  • [LeetCode/LintCode] Number of Islands [DFS]

    摘要:两个循环遍历整个矩阵,出现则将其周围相邻的全部标记为,用子函数递归标记。注意里每次递归都要判断边界。写一个的,写熟练。 Number of Islands Problem Given a boolean/char 2D matrix, find the number of islands. 0 is represented as the sea, 1 is represented as...

    Fourierr 评论0 收藏0
  • [LeetCode] 694. Number of Distinct Islands

    Problem Given a non-empty 2D array grid of 0s and 1s, an island is a group of 1s (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are s...

    SunZhaopeng 评论0 收藏0
  • leetcode200. Number of Islands

    摘要:题目要求提供一个二维数组表示一张地图,其中代表陆地,代表海洋。这里使用一个新的二维数组来表示对应地图上的元素属于哪个并查集。在合并的时候先进行判断,如果二者为已经相连的陆地,则无需合并,否则将新的二维数组上的元素指向所在的并查集。 题目要求 Given a 2d grid map of 1s (land) and 0s (water), count the number of isla...

    Zoom 评论0 收藏0
  • 前端 | 每天一个 LeetCode

    摘要:在线网站地址我的微信公众号完整题目列表从年月日起,每天更新一题,顺序从易到难,目前已更新个题。这是项目地址欢迎一起交流学习。 这篇文章记录我练习的 LeetCode 题目,语言 JavaScript。 在线网站:https://cattle.w3fun.com GitHub 地址:https://github.com/swpuLeo/ca...我的微信公众号: showImg(htt...

    张汉庆 评论0 收藏0

发表评论

0条评论

Raaabbit

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<