当前位置: 首页 > ai >正文

岛屿数量问题

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [
[“1”,“1”,“1”,“1”,“0”],
[“1”,“1”,“0”,“1”,“0”],
[“1”,“1”,“0”,“0”,“0”],
[“0”,“0”,“0”,“0”,“0”]
]
输出:1
示例 2:
输入:grid = [
[“1”,“1”,“0”,“0”,“0”],
[“1”,“1”,“0”,“0”,“0”],
[“0”,“0”,“1”,“0”,“0”],
[“0”,“0”,“0”,“1”,“1”]
]
输出:3
LeetCode链接:https://leetcode.cn/problems/number-of-islands/description/

开始思路

        递归查找当前区域的上下左右,如果有连接的岛屿,就继续递归查找,为了防止重复查找,使用island数组,给不同的岛屿不同的id,并将查找过的海域标记。

/*
整体思路:
1、递归查找,每次传入:map:岛屿starX:下次查找的x坐标starY:下次查找的Y坐标flag:岛屿的标识2、island中不同的岛屿用不同的数字标示:0:未被查找0<i:第i个岛屿,且已被查找-1:此处为海水3、结束条件:island中不存在未被查找的区域 -> return当前区域为海,或者已被访问 -> return当前区域四面环海 -> flag++*/class Solution {
private:int m, n;vector<vector<int>> island;int moveStep[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};int set[1][2] = {{0, 0}};//岛屿是否被查找过bool isFind(int x, int y) {if (island[x][y] == 0)return false;return true;}//是否所有区域都被查找了bool isAllFind() {for (int i = 0; i < island.size(); i++) {for (int j = 0; j < island[i].size(); j++) {if (0 == island[i][j])return false;}}return true;}//当前坐标是否在海域内bool inLand(int x, int y) { return 0 <= x && x < m && 0 <= y && y < n; }//当前岛屿是否已经被完全搜索bool landEnd(int x, int y) {int _x;int _y;for (int i = 0; i < 4; i++) {_x = x + moveStep[i][0];_y = y + moveStep[i][1];if (inLand(_x, _y) && (0 == island[_x][_y])) {return false;}}return true;}//返回被没有查找到的岛屿的起始坐标bool newLand(vector<vector<char>>& map) {for (int i = 0; i < island.size(); i++) {for (int j = 0; j < island[i].size(); j++) {if (!isFind(i, j) && '1' == map[i][j]) {set[0][0] = i;set[0][1] = j;return true;}}}return false;}//递归的查找岛屿void findIsland(vector<vector<char>>& map, int starX, int starY, int flag) {int _x, _y;if (isAllFind()) {return;}if (isFind(starX, starY)) {return;}if (inLand(starX, starY) && 0 == island[starX][starY]) {if ('0' == map[starX][starY]) {island[starX][starY] = -1;return;}island[starX][starY] = flag;}for (int i = 0; i < 4; i++) {_x = starX + moveStep[i][0];_y = starY + moveStep[i][1];if (inLand(_x, _y) && 0 == island[_x][_y]) {// island[_x][_y] = flag;findIsland(map, _x, _y, flag);}}if (landEnd(starX, starY)) {if (newLand(map)) {findIsland(map, set[0][0], set[0][1], flag+1);}}}public:int numIslands(vector<vector<char>>& grid) {int islandNum = 0;m = grid.size();if (m == 0) {return 0;}n = grid[0].size();island = vector<vector<int>>(m, (vector<int>(n, 0)));//从岛屿开始newLand(grid);findIsland(grid, set[0][0], set[0][1], 1);//岛屿中flag最大值为所有岛屿数for (int i = 0; i < island.size(); i++) {for (int j = 0; j < island[i].size(); j++) {if (islandNum < island[i][j])islandNum = island[i][j];}}return islandNum;}
};

不过该方法存在错误,仅通过部分测试用例:
在这里插入图片描述

解题思路

        开始想复杂了,其实可以分为两步:1、找到未被访问的岛屿;2、遍历岛屿全部陆地。然后遍历地图全部区域即可。

class Solution {
private:int Row, Col, landNum = 0;int moveStep[4][2] = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}};vector<vector<bool>> isVisit;//是否在地图内bool inLand(int k, int l) {if (k < 0 || k >= Row)return false;if (l < 0 || l >= Col)return false;return true;}//标记当前岛屿全部陆地void findLand(vector<vector<char>>& grid, int X, int Y) {int _x, _y;isVisit[X][Y] = true;for (int i = 0; i < 4; i++) {if (inLand(X + moveStep[i][0], Y + moveStep[i][1]) &&!isVisit[X + moveStep[i][0]][Y + moveStep[i][1]] &&(grid[X + moveStep[i][0]][Y + moveStep[i][1]] == '1')) {findLand(grid, X + moveStep[i][0], Y + moveStep[i][1]);}}}public:int numIslands(vector<vector<char>>& grid) {Row = grid.size();if (0 == Row) {cout << "Row is NULL";return 0;}Col = grid[Row - 1].size();//是否被访问过isVisit = vector<vector<bool>>(Row, (vector<bool>(Col, false)));//遍历全部for (int i = 0; i < Row; i++)for (int j = 0; j < Col; j++)//如果当前是岛屿,且没有被访问过if (!isVisit[i][j] && (grid[i][j] == '1')) {//岛屿数量加一;landNum++;//遍历岛屿全部陆地findLand(grid, i, j);}return landNum;}
};

代码运行结果:
请添加图片描述

http://www.xdnf.cn/news/15209.html

相关文章:

  • HT8313功放入门
  • Cell2location maps fine-grained cell types in spatial transcriptomics 文章解析
  • Golang操作MySQL json字段优雅写法
  • 【数据结构初阶】--顺序表(三)
  • 【机器学习实战笔记 16】集成学习:LightGBM算法
  • 【读书笔记】从AI到Transformer:LLM技术演进全解析
  • 智能Agent场景实战指南 Day 11:财务分析Agent系统开发
  • 动态规划基本操作
  • Vue3 学习教程,从入门到精通,Vue3指令知识点及使用方法详细介绍(6)
  • 【TOOL】ubuntu升级cmake版本
  • Linux驱动08 --- 数据库
  • 【PTA数据结构 | C语言版】后缀表达式求值
  • Mamba架构的模型 (内容由deepseek辅助汇总)
  • Edge浏览器:报告不安全的站点的解决方案
  • JAVA线程池详解+学习笔记
  • 鸿蒙NDK开发技巧之-----HAP包如何引入HSP包后,如何给HSP的包传递上下文
  • 非欧几里得空间图卷积算子设计:突破几何限制的图神经网络新范式
  • 从LLM到VLM:视觉语言模型的核心技术与Python实现
  • 如何搭建一个高质量的开放接口平台
  • 顺序队列和链式队列
  • HTML(上)
  • 混合精度训练:梯度缩放动态调整的艺术与科学
  • day4--上传图片、视频
  • AI软件出海SEO教程
  • 从 Spring 源码到项目实战:设计模式落地经验与最佳实践
  • nginx反向代理实现跨域请求
  • 基于springboot+Vue的二手物品交易的设计与实现
  • ABP VNext + OpenTelemetry + Jaeger:分布式追踪与调用链可视化
  • C语言32个关键字
  • WebGL简易教程——结语