作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/number-of-islands/description/

题目描述

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:

Input:
11110
11010
11000
00000 Output: 1

Example 2:

Input:
11000
11000
00100
00011 Output: 3

题目大意

有一片水域,四联通的算一个岛,求所有的岛的数目。

解题方法

DFS

这个题在《挑战程序设计竞赛》书的前面就讲了,我觉得还是挺经典的题目。可以直接套模板解决。

做法是,我们对每个有“1"的位置进行 DFS,把和它四联通的位置全部变成“0”,这样就能把一个点推广到一个岛。

所以,我们总的进行了 DFS 的次数,就是总过有多少个岛的数目。

注意理解dfs函数的意义:已知当前是1,把它周围相邻的所有1全部转成0.

代码如下:

class Solution:
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
res = 0
for r in range(len(grid)):
for c in range(len(grid[0])):
if grid[r][c] == "1":
self.dfs(grid, r, c)
res += 1
return res def dfs(self, grid, i, j):
dirs = [[-1, 0], [0, 1], [0, -1], [1, 0]]
grid[i][j] = "0"
for dir in dirs:
nr, nc = i + dir[0], j + dir[1]
if nr >= 0 and nc >= 0 and nr < len(grid) and nc < len(grid[0]):
if grid[nr][nc] == "1":
self.dfs(grid, nr, nc)

C++版本的代码如下:

class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
if (grid.empty() || grid[0].empty())
return 0;
const int M = grid.size();
const int N = grid[0].size();
int res = 0;
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
if (grid[i][j] == '1') {
res ++;
dfs(grid, i, j);
}
}
}
return res;
}
void dfs(vector<vector<char>>& grid, int x, int y) {
grid[x][y] = '0';
const int M = grid.size();
const int N = grid[0].size();
for (auto& dir : dirs) {
int nx = x + dir[0];
int ny = y + dir[1];
if (nx < 0 || nx >= M || ny < 0 || ny >= N || grid[nx][ny] == '0')
continue;
dfs(grid, nx, ny);
}
}
private:
vector<vector<int>> dirs = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
};

BFS

这个题同样可以使用BFS解决。当遇到一个小岛的时候,做个BFS搜索,把它周围的小岛全部转成0即可。速度比DFS稍微慢了一点点。

Python 代码如下:

class Solution(object):
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
if not grid or not grid[0]: return 0
M, N = len(grid), len(grid[0])
que = collections.deque()
res = 0
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for i in range(M):
for j in range(N):
if grid[i][j] == '1':
res += 1
grid[i][j] = '0'
que.append((i, j))
while que:
x, y = que.pop()
for d in directions:
nx, ny = x + d[0], y + d[1]
if 0 <= nx < M and 0 <= ny < N and grid[nx][ny] == '1':
grid[nx][ny] = '0'
que.append((nx, ny))
return res

在写 BFS 的时候可以把代码包装成一个函数,需要注意的是,由于BFS会把周围的1全部改成0,所以在出队列的时候,做一个判断,如果当前围着孩子已经被改了,那么就不用下面的搜索了。

C++代码如下:

class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
if (grid.size() == 0 || grid[0].size() == 0) return 0;
const int M = grid.size(), N = grid[0].size();
int res = 0;
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
if (grid[i][j] == '1') {
++res;
bfs(grid, i, j);
}
}
}
return res;
}
// gird[x][y] = 1, delete it and its around.
void bfs(vector<vector<char>>& grid, int x, int y) {
const int M = grid.size(), N = grid[0].size();
queue<pair<int, int>> q;
q.push({x, y});
while (!q.empty()) {
auto head = q.front(); q.pop();
int x = head.first;
int y = head.second;
if (grid[x][y] != '1') continue;
grid[x][y] = '0';
for (auto d : dirs) {
int i = x + d.first;
int j = y + d.second;
if (i < 0 || i >= M || j < 0 || j >= N || grid[i][j] != '1') {
continue;
}
q.push({i, j});
}
}
}
private:
vector<pair<int, int>> dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
};

日期

2018 年 7 月 20 日 —— 北京的阴雨天,又闷又潮
2019 年 1 月 8 日 —— 别熬夜,我都开始有黑眼圈了。。
2020 年 4 月 20 日 —— 没想到我也会熬夜看剧

【LeetCode】200. Number of Islands 岛屿数量的更多相关文章

  1. LeetCode 200. Number of Islands 岛屿数量(C++/Java)

    题目: Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is s ...

  2. [leetcode]200. Number of Islands岛屿数量

    dfs的第一题 被边界和0包围的1才是岛屿,问题就是分理出连续的1 思路是遍历数组数岛屿,dfs四个方向,遇到1后把周围连续的1置零,代表一个岛屿. /* 思路是:遍历二维数组,遇到1就把周围连续的1 ...

  3. [LeetCode] 200. Number of Islands 岛屿的数量

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  4. [leetcode]200. Number of Islands岛屿个数

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  5. leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions

    两种方式处理已经访问过的节点:一种是用visited存储已经访问过的1:另一种是通过改变原始数值的值,比如将1改成-1,这样小于等于0的都会停止. Number of Islands 用了第一种方式, ...

  6. [LeetCode] 0200. Number of Islands 岛屿的个数

    题目 Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is su ...

  7. Java for LeetCode 200 Number of Islands

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  8. (BFS/DFS) leetcode 200. Number of Islands

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  9. Leetcode 200. number of Islands

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

随机推荐

  1. 42-Remove Nth Node From End of List

    Remove Nth Node From End of List My Submissions QuestionEditorial Solution Total Accepted: 106592 To ...

  2. 谈谈AI

    由AI大作业想到的 近几年<人工智能导论>的大作业是编写一个博弈程序,这类程序的典型框架就是α-β剪枝算法,像著名的打败了国际象棋大师卡斯帕罗的深蓝,就是这么干的,一些中国象棋程序也是这样 ...

  3. sqlalchemy模块的基本使用

    Python中SQLAlchemy模块通过建立orm来对数据库进行操作 1. 建表 方式1 # -*- coding:utf-8 -*- # Author:Wong Du from sqlalchem ...

  4. Docker网络设置及文件挂载

    网络设置–net=bridge- 默认选项,用网桥的方式来连接docker容器.–net=host- docker跳过配置容器的独立网络栈.–net=container:NAME_or_ID- 告诉d ...

  5. MIT6.824 分布式系统实验

    LAB1 mapreduce mapreduce中包含了两个角色,coordinator和worker,其中,前者掌管任务的分发和回收,后者执行任务.mapreduce分为两个阶段,map阶段和red ...

  6. 双向循环链表模板类(C++)

    双向链表又称为双链表,使用双向链表的目的是为了解决在链表中访问直接前驱和后继的问题.其设置前驱后继指针的目的,就是为了节省其时间开销,也就是用空间换时间. 在双向链表的每个节点中应有两个链接指针作为它 ...

  7. Oracle参数文件—pfile与spfile

    oracle的参数文件:pfile和spfile 1.pfile和spfile       Oracle中的参数文件是一个包含一系列参数以及参数对应值的操作系统文件.它们是在数据库实例启动时候加载的, ...

  8. awk统计命令(求和、求平均、求最大值、求最小值)

    本节内容:awk统计命令 1.求和 cat data|awk '{sum+=$1} END {print "Sum = ", sum}' 2.求平均 cat data|awk '{ ...

  9. SQL Server中修改“用户自定义表类型”问题的分析与方法

    前言 SQL Server开发过程中,为了传入数据集类型的变量(比如接受C#中的DataTable类型变量),需要定义"用户自定义表类型",通过"用户自定义表类型&quo ...

  10. Vuejs-网络

    1.axios是什么 是基于promise用于浏览器和node.js的http客户端一个js库,基于Promise这点要好好理解一下. 2.特点 支持浏览器和node.js 支持promise 能拦截 ...