KamaCoder 99. 岛屿数量 + Leetcode 200. Number of Islands

99. 岛屿数量

题目描述:

给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。

输入描述:

第一行包含两个整数 N, M,表示矩阵的行数和列数。

后续 N 行,每行包含 M 个数字,数字为 1 或者 0。

输出描述:

输出一个整数,表示岛屿的数量。如果不存在岛屿,则输出 0。

输入示例:

根据测试案例中所展示,岛屿数量共有 3 个,所以输出 3。

思路

深度优先搜索

注意题目中每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

也就是说斜角度链接是不算了, 例如示例二,是三个岛屿,如图:

考虑遇到一个没有访问过的节点陆地,计数器就加1,然后把该节点陆地所能遍历到的陆地都标记上。

再遇到标记过的陆地节点和海洋节点的时候直接跳过。这样就得到了岛屿的最终数量。

广度优先搜索

这里有一个广搜中很重要的细节:

根本原因是只要 加入队列就代表 走过,就需要标记,而不是从队列拿出来的时候再去标记走过

如果从队列拿出节点,再去标记这个节点走过,就会发生下图所示的结果,会导致很多节点重复加入队列。

代码

C++深度优先搜索(DFS这里只起到标记位置的作用,一次找出整个岛)

#include <iostream>
#include <vector>
using namespace std;int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
void dfs(const vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {for (int i = 0; i < 4; ++i) {int nextx = x + dir[i][0];int nexty = y + dir[i][1];if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) {continue; // 越界了,直接跳过}if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) {// 没有访问过,同时是陆地visited[nextx][nexty] = true;dfs(grid, visited, nextx, nexty);}}
}int main() {int n, m;cin >> n >> m;vector<vector<int>> grid(n, vector<int>(m, 0));for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {cin >> grid[i][j];}}vector<vector<bool>> visited(n, vector<bool>(m, false));int result = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (!visited[i][j] && grid[i][j] == 1) {visited[i][j] = true;result++;dfs(grid, visited, i, j); // 将与其链接的岛屿都标记上true}}}cout << result << endl;
}

C++广度优先搜索(把同一个岛屿的遍历在一个BFS内完成)

#include <iostream>
#include <vector>
#include <queue>
using namespace std;int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
void bfs(const vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {queue<pair<int, int>> que;que.push({x, y});visited[x][y] = true;while (!que.empty()) {pair<int, int> cur = que.front(); que.pop();int curx = cur.first;int cury = cur.second;for (int i = 0; i < 4; ++i) {int nextx = curx + dir[i][0];int nexty = cury + dir[i][1];if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) {que.push({nextx, nexty}); // 压进队列,之后再检查。而不是像DFS一样,一路走到底。(没有BFS的套用)visited[nextx][nexty] = true; // 只要压进队列立刻标记}}}
}int main() {int n, m;cin >> n >> m;vector<vector<int>> grid(n, vector<int>(m, 0));for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {cin >> grid[i][j];}}vector<vector<bool>> visited(n, vector<bool>(m, false));int result = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (!visited[i][j] && grid[i][j] == 1) {visited[i][j] = true;result++; // 结果再进入BFS之前累加,因为找到了新岛屿bfs(grid, visited, i, j); // 将与其链接的岛屿都标记上true}}}cout << result << endl;
}

Python深度优先搜索

from collections import dequedir = [(0, 1), (1, 0), (0, -1), (-1, 0)]def dfs(grid, visited, x, y):for dx, dy in dir:nextx, nexty = x + dx, y + dyif nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):continueif grid[nextx][nexty] == 1 and not visited[nextx][nexty]:visited[nextx][nexty] = Truedfs(grid, visited, nextx, nexty)def main():n, m = map(int, input().split())grid = [list(map(int, input().split())) for _ in range(n)] # 'map'函数返回的是一个迭代器,而不是一个列表。为了将其转换为列表,我们使用 list() 函数将迭代器转化为一个具体的列表。visited = [[False] * (m) for _ in range(n)]result = 0for i in range(n):for j in range(m):if (grid[i][j] == 1 and not visited[i][j]):result += 1visited[i][j] = Truedfs(grid, visited, i, j)print(result)if __name__ == "__main__":main()

Python广度优先搜索

from collections import dequedir = [(0, 1), (1, 0), (0, -1), (-1, 0)]def bfs(grid, visited, x, y):queue = deque([(x, y)])visited[x][y] = Truewhile (queue):curx, cury = queue.popleft()for dx, dy in dir:nextx, nexty = curx + dx, cury + dyif nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]): # 注意这里从0开始所以比n,m小1,如果等于的时候实际上已经越界continueif not visited[nextx][nexty] and grid[nextx][nexty] == 1:queue.append((nextx, nexty))visited[nextx][nexty] = Truedef main():n, m = map(int, input().split())grid = [list(map(int, input().split())) for _ in range(n)] # 'map'函数返回的是一个迭代器,而不是一个列表。为了将其转换为列表,我们使用 list() 函数将迭代器转化为一个具体的列表。visited = [[False] * (m) for _ in range(n)]result = 0for i in range(n):for j in range(m):if (grid[i][j] == 1 and not visited[i][j]):result += 1visited[i][j] = Truebfs(grid, visited, i, j)print(result)if __name__ == "__main__":main()

Leetcode 200. Number of Islands

C++广度优先搜索 (字符用单引号,字符串用双引号)

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
class Solution {
public:int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};void bfs(const vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) {queue<pair<int, int>> que;que.push({x, y});visited[x][y] = true;while (!que.empty()) {pair<int, int> cur = que.front(); que.pop();int curx = cur.first;int cury = cur.second;for (int i = 0; i < 4; ++i) {int nextx = curx + dir[i][0];int nexty = cury + dir[i][1];if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;if (!visited[nextx][nexty] && grid[nextx][nexty] == '1') {que.push({nextx, nexty}); // 压进队列,之后再检查。而不是像DFS一样,一路走到底。(没有BFS的套用)visited[nextx][nexty] = true; // 只要压进队列立刻标记}}}}int numIslands(vector<vector<char>>& grid) {int n = grid.size();int m = grid[0].size();vector<vector<bool>> visited(n, vector<bool>(m, false));int result = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (!visited[i][j] && grid[i][j] == '1') {visited[i][j] = true;result++; // 结果再进入BFS之前累加,因为找到了新岛屿bfs(grid, visited, i, j); // 将与其链接的岛屿都标记上true}}}return result;}
};

Python深度优先搜索

class Solution:dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]def dfs(self, grid, visited, x, y):for dx, dy in self.dir:nextx, nexty = x + dx, y + dyif nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):continueif grid[nextx][nexty] == '1' and not visited[nextx][nexty]:visited[nextx][nexty] = Trueself.dfs(grid, visited, nextx, nexty)def numIslands(self, grid: List[List[str]]) -> int:n, m = len(grid), len(grid[0])visited = [[False] * (m) for _ in range(n)]result = 0for i in range(n):for j in range(m):if (grid[i][j] == '1' and not visited[i][j]):result += 1visited[i][j] = Trueself.dfs(grid, visited, i, j)return result

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/51084.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode】栈 - 20.有效的括号、150.逆波兰表达式求值、155.最小栈、栈的压入、弹出序列

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

【前端/js】使用js读取本地文件(xml、二进制)内容

目录 说在前面FileReaderDOMParser文本文件二进制文件 说在前面 浏览器版本&#xff1a;Microsoft Edge 126.0.2 (正式版本) (64 位) FileReader MDNFileReader 接口允许 Web 应用程序异步读取存储在用户计算机上的文件&#xff08;或原始数据缓冲区&#xff09;的内容&#x…

分布式光伏并网AM5SE-IS防孤岛保护装置介绍——安科瑞 叶西平

产品简介 功能&#xff1a; AM5SE-IS防孤岛保护装置主要适用于35kV、10kV及低压380V光伏发电、燃气发电等新能源并网供电系统。当发生孤岛现象时&#xff0c;可以快速切除并网点&#xff0c;使本站与电网侧快速脱离&#xff0c;保证整个电站和相关维护人员的生命安全。 应用…

模拟实现c++中的vector模版

目录 一vector简述&#xff1a; 二vector的一些接口函数&#xff1a; 1初始化&#xff1a; 2.vector增长&#xff1a; 3vector增删查改&#xff1a; 三vector模拟实现部分主要函数&#xff1a; 1.size,capacity,empty,clear接口&#xff1a; 2.reverse的实现&#xff1…

Golang | Leetcode Golang题解之第292题Nim游戏

题目&#xff1a; 题解&#xff1a; func canWinNim(n int) bool {return n%4 ! 0 }

【一图学技术】SDK和API有什么关系?

API&#xff08;应用程序编程接口&#xff09;&#xff1a; API是一组定义了软件组件之间交互的规则和协议。 它定义了如何请求某个功能或服务&#xff0c;并指定了数据的格式和传输方式。API 可以用于不同的编程语言和平台。 API提供了一种标准化的方式&#xff0c;使不同的应…

[译] 深入浅出Rust基金会

本篇是对 RustConf 2023中的Rust Foundation: Demystified这一视频的翻译与整理, 过程中为符合中文惯用表达有适当删改, 版权归原作者所有. 大家好,我是Sage Griffin,我的代词是they/them。我今天来这里是要谈谈Rust基金会。 要了解基金会实际做什么,我们需要理解美国国内税收…

6.3 面向对象技术-设计模式

设计模式 创建型模式 结构型模式

布尔盲注——多种方式实现及利用burpsuite爆破

目录 1、判断闭合符类型 2、爆数据库长度 3、查询库名 手动注入 burpsuite爆破 方法一&#xff1a;用ASCII码值转化爆破 方法二&#xff1a;left方法直接爆破字母 方法三&#xff1a;if方法爆破注入&#xff08;最简单&#xff09; 4、爆破表名 5、爆破具体值 当我们改变前端…

Java | Leetcode Java题解之第279题完全平方数

题目&#xff1a; 题解&#xff1a; class Solution {public int numSquares(int n) {if (isPerfectSquare(n)) {return 1;}if (checkAnswer4(n)) {return 4;}for (int i 1; i * i < n; i) {int j n - i * i;if (isPerfectSquare(j)) {return 2;}}return 3;}// 判断是否为…

夜不能寐?解锁失眠自救秘籍,让你重拾安睡之夜!

在这个快节奏的时代&#xff0c;失眠似乎成了许多人的“隐形伴侣”&#xff0c;悄悄侵蚀着我们的健康与幸福感。夜深人静&#xff0c;万籁俱寂之时&#xff0c;你却辗转反侧&#xff0c;难以入眠&#xff0c;第二天又拖着疲惫的身躯迎接新的挑战。别担心&#xff0c;今天我们就…

大脑自组织神经网络通俗讲解

大脑自组织神经网络的核心概念 大脑自组织神经网络&#xff0c;是指大脑中的神经元通过自组织的方式形成复杂的网络结构&#xff0c;从而实现信息的处理和存储。这一过程涉及到神经元的生长、连接和重塑&#xff0c;是大脑学习和记忆的基础。其核心公式涉及神经网络的权重更新…

二分法各种边界,大彻大悟

1要考虑四个角度的“边界”&#xff0c;如下图 2 先考虑角度a的第一种情况 如下图所示&#xff0c;对于左边的情况&#xff0c;因为当l3&#xff0c;r4的时候&#xff0c;mid等于3&#xff0c;已知target4, 如果lmid就陷入死循环&#xff0c;所以l。右边同理。 判断c1 c2的影…

热门音效、BGM哪里可以免费下载?

剪辑的奇妙世界等你探索&#xff01;在这个创意的领域里&#xff0c;音效是创造氛围、增强表现力的重要元素。我整理了8个优质的剪辑音效素材网站&#xff0c;它们提供了丰富多样的音效资源&#xff0c;无论是制作视频、音乐还是动画&#xff0c;都能为你提供所需的声音。 1、b…

大模型学习笔记十四:Agent模型微调

文章目录 一、大模型需要Agent技术的原因二、Prompt Engineering可以实现Agent吗&#xff1f;&#xff08;1&#xff09;ReAct原理展示和代码&#xff08;2&#xff09;ModelScope&#xff08;3&#xff09;AutoGPT&#xff08;4&#xff09;ToolLLaMA 三、既然AutoGPT可以满足…

LaTeX如何改变字体颜色

诸神缄默不语-个人CSDN博文目录 在LaTeX文档中&#xff0c;改变字体颜色是一个常见需求&#xff0c;尤其是在需要强调特定文本或使文档更加生动的时候。本文将介绍如何使用\color{}命令来更改字体颜色。 文章目录 基本用法示例代码预定义颜色使用自定义颜色总结本文撰写过程中…

助力樱桃智能自动化采摘,基于嵌入式端超轻量级模型LeYOLO全系列【n/s/m/l】参数模型开发构建果园种植采摘场景下樱桃成熟度智能检测识别系统

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术已经渗透到我们生活的方方面面&#xff0c;从智能家居到自动驾驶&#xff0c;再到医疗健康&#xff0c;其影响力无处不在。然而&#xff0c;当我们把目光转向中国的农业领域时&#xff0c;一个令人惊讶的…

跟《经济学人》学英文:2024年07月20日这期 A short history of AI

A short history of AI In the first of six weekly briefs, we ask how AI overcame decades of underdelivering 原文&#xff1a; Over the summer of 1956 a small but illustrious group gathered at Dartmouth College in New Hampshire; it included Claude Shannon,…

五、Spring Boot - 上手篇(1)

&#x1f33b;&#x1f33b;目录 一、快速入门&#xff1a;创建第一个SpringBoot 工程1.1 点击File--->New--->Project...1.2 选择版本和依赖的相关骨架包1.3 设置项目保存目录1.4 项目创建完成&#xff0c;工程主界面如下1.5 项目说明1.6 启动项目1.7 编写 HelloControl…