力扣第695题 岛屿的最大面积 C++ DFS BFS 附Java代码

题目

695. 岛屿的最大面积

中等

相关标签

深度优先搜索   广度优先搜索   并查集   数组   矩阵

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

示例 1:

输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
输出:6
解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1。

示例 2:

输入:grid = [[0,0,0,0,0,0,0,0]]
输出:0

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j] 为 0 或 1

思路和解题方法 1 DFS

  1. dfs 函数通过传入的坐标 (x, y) 来探索当前陆地区域的情况。如果当前坐标越界(超出了网格范围)或者是海洋(值为 0),则返回面积 0,表示此处不是陆地。

  2. 如果当前坐标是陆地(值为 1),则将其标记为已访问过(即将值置为 0),以免重复访问同一块陆地。然后开始向当前位置的上、下、左、右四个方向进行深度优先搜索,探索与当前陆地相连的其他陆地。

  3. 在每一步深度优先搜索中,我们累加当前陆地的面积,并递归地探索相邻的陆地。这样,通过深度优先搜索,我们能够计算出以当前位置为起点的整个连通陆地区域的面积。

  4. 最后,将累计的面积作为返回值返回给上一级递归调用。

maxAreaOfIsland 函数中,我们遍历整个网格,对于每个岛屿的起始位置(即值为 1 的位置),调用 dfs 函数来计算以该位置为起点的岛屿的面积。并将得到的面积与当前记录的最大面积进行比较,并更新最大面积的值。

时间复杂度分析:

  • 对于每个格子,最坏情况下需要进行深度优先搜索,而深度优先搜索的时间复杂度是 O(m*n),其中 m 和 n 分别为 grid 的行数和列数。
  • 因此,总的时间复杂度为 O(m*n),其中 m 为 grid 的行数,n 为 grid 的列数。

空间复杂度分析:

  • 深度优先搜索过程中使用的递归调用栈的最大深度为岛屿的大小,最坏情况下为整个 grid 大小,因此空间复杂度为 O(m*n)。
  • 此外,还需要考虑输入参数和一些辅助变量的空间占用,但是这些空间占用都是常数级别的,因此不影响总体的空间复杂度。

综上所述,该算法的时间复杂度为 O(mn),空间复杂度也为 O(mn)。

c++ 代码

class Solution {
public:// 深度优先搜索函数,用于搜索连通的岛屿区域并返回面积int dfs(vector<vector<int>>& grid, int x, int y) {// 递归终止条件if (x < 0 || x == grid.size() || y < 0 || y == grid[0].size() || grid[x][y] == 0) return 0;grid[x][y] = 0; // 将已经搜索过的陆地置为0,防止重复搜索(即将其视为沉没的岛屿)int ans = 1;// 分别搜索当前陆地的上、下、右、左四个方向的区块ans += dfs(grid, x, y + 1); // 上面ans += dfs(grid, x, y - 1); // 下面ans += dfs(grid, x + 1, y); // 右边ans += dfs(grid, x - 1, y); // 左边return ans;  // 返回当前连通岛屿的总面积}// 计算最大岛屿面积的函数int maxAreaOfIsland(vector<vector<int>>& grid) {int ans = 0;  // 初始化最大面积为0for (int i = 0; i != grid.size(); ++i) {for (int j = 0; j != grid[0].size(); ++j) {if (grid[i][j] == 1) {  // 如果当前位置是陆地int cnt = dfs(grid, i, j);  // 对当前的岛屿区域进行深度优先搜索,得到面积ans = max(ans, cnt);  // 更新最大面积}}}return ans;  // 返回最大岛屿面积}
};

思路和解题方法 2 BFS

  1. 首先,定义了一个类 Solution,其中包含了一个公有函数 maxAreaOfIsland,该函数接收一个二维向量 grid 作为参数,并返回岛屿的最大面积。

  2. maxAreaOfIsland 函数中,我们首先初始化 ans 为 0,以便记录最大的岛屿面积。

  3. 接下来是两个嵌套的 for 循环,用来遍历整个二维网格 grid

  4. 在每次迭代中,我们首先初始化 cur 为 0,用于记录当前岛屿的面积。然后创建两个队列 queueiqueuej,用于存储待访问的陆地坐标。

  5. 将当前遍历到的位置 (i, j) 入队,即将它们分别加入到 queueiqueuej 中。

  6. 进入while循环,只要队列非空,就不断进行以下操作:

    • 弹出队首的坐标 (cur_i, cur_j)
    • 检查当前坐标是否越界或者不是陆地,若是则跳过本次循环;
    • 若当前坐标是陆地,则将当前面积 cur 自增,并将当前坐标标记为已访问过的海洋(即将值置为 0),然后探索当前位置的上、下、左、右四个方向;
    • 将相邻的陆地坐标入队。
  7. 在每次内部循环结束时,更新 ans 为当前 curans 之间的较大值。

  8. 最后,遍历结束后返回 ans,即为岛屿的最大面积。

时间复杂度分析:

  • 时间复杂度取决于岛屿的数量和网格的大小。假设网格的行数为 m,列数为 n,岛屿的数量为 k,那么时间复杂度可以表示为 O(mn+k),其中 mn 表示遍历整个网格的时间复杂度,k 表示计算岛屿面积的时间复杂度。

空间复杂度分析:

  • 空间复杂度方面,使用了两个队列 queueiqueuej,它们的最大长度可以达到网格的面积大小,因此空间复杂度也是 O(m*n)。

综上所述,该算法的时间复杂度为 O(mn),空间复杂度也为 O(mn)。

c++ 代码

class Solution {
public:int maxAreaOfIsland(vector<vector<int>>& grid) {int ans = 0;// 遍历二维网格的每一个位置for (int i = 0; i != grid.size(); ++i) {for (int j = 0; j != grid[0].size(); ++j) {int cur = 0;  // 当前岛屿的面积queue<int> queuei;queue<int> queuej;queuei.push(i);  // 将当前位置加入队列queuej.push(j);while (!queuei.empty()) {int cur_i = queuei.front(), cur_j = queuej.front();  // 取出队首元素queuei.pop();queuej.pop();if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1) {continue;  // 如果当前位置超出边界或者不是岛屿,跳过}++cur;  // 当前岛屿面积加一grid[cur_i][cur_j] = 0;  // 将当前位置置为0,表示已经访问过int di[4] = {0, 0, 1, -1};  // 方向数组,表示上下左右四个方向int dj[4] = {1, -1, 0, 0};for (int index = 0; index != 4; ++index) {int next_i = cur_i + di[index], next_j = cur_j + dj[index];  // 计算四个相邻位置queuei.push(next_i);  // 将相邻位置加入队列queuej.push(next_j);}}ans = max(ans, cur);  // 更新最大岛屿面积}}return ans;  // 返回最大岛屿面积}
};

附Java代码

DFS

class Solution {public int maxAreaOfIsland(int[][] grid) {int ans = 0;  // 初始化最大岛屿面积为0for (int i = 0; i != grid.length; ++i) {  // 遍历二维网格的每一个位置for (int j = 0; j != grid[0].length; ++j) {ans = Math.max(ans, dfs(grid, i, j));  // 计算以当前位置为起点的岛屿面积,并更新最大值}}return ans;  // 返回最大岛屿面积}public int dfs(int[][] grid, int cur_i, int cur_j) {if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {return 0;  // 如果当前位置超出边界或者不是岛屿,返回面积为0}grid[cur_i][cur_j] = 0;  // 将当前位置置为0,表示已经访问过int[] di = {0, 0, 1, -1};  // 方向数组,表示上下左右四个方向int[] dj = {1, -1, 0, 0};int ans = 1;  // 当前岛屿面积初始化为1for (int index = 0; index != 4; ++index) {int next_i = cur_i + di[index], next_j = cur_j + dj[index];  // 计算四个相邻位置ans += dfs(grid, next_i, next_j);  // 递归计算相邻位置的岛屿面积并累加}return ans;  // 返回当前岛屿面积}
}

BFS

class Solution {// 计算岛屿的最大面积public int maxAreaOfIsland(int[][] grid) {int ans = 0;  // 初始化最大面积为 0// 遍历整个网格for (int i = 0; i != grid.length; ++i) {for (int j = 0; j != grid[0].length; ++j) {int cur = 0;  // 当前岛屿的面积Queue<Integer> queuei = new LinkedList<Integer>();  // 存储陆地坐标的队列Queue<Integer> queuej = new LinkedList<Integer>();  // 存储陆地坐标的队列queuei.offer(i);  // 将当前坐标入队queuej.offer(j);  // 将当前坐标入队// BFS 遍历岛屿while (!queuei.isEmpty()) {int cur_i = queuei.poll(), cur_j = queuej.poll();  // 出队当前坐标// 检查当前坐标是否越界或者不是陆地,若是则跳过本次循环if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {continue;}++cur;  // 当前岛屿的面积加一grid[cur_i][cur_j] = 0;  // 标记当前坐标为已访问过的海洋int[] di = {0, 0, 1, -1};  // 方向数组,分别表示上、下、左、右四个方向int[] dj = {1, -1, 0, 0};  // 方向数组,分别表示上、下、左、右四个方向// 探索当前位置的上、下、左、右四个方向for (int index = 0; index != 4; ++index) {int next_i = cur_i + di[index], next_j = cur_j + dj[index];  // 计算相邻坐标queuei.offer(next_i);  // 将相邻的陆地坐标入队queuej.offer(next_j);  // 将相邻的陆地坐标入队}}ans = Math.max(ans, cur);  // 更新最大面积}}return ans;  // 返回岛屿的最大面积}
}

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

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

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

相关文章

2023年中国骨质疏松治疗仪发展趋势分析:小型且智能将成为产品优化方向[图]

骨质疏松治疗仪利用磁场镇静止痛、消肿消炎的治疗作用迅速缓解患者腰背疼痛等骨质疏松临床症状。同时利用磁场的磁-电效应产生的感生电势和感生电流&#xff0c;改善骨的代谢和骨重建&#xff0c;通过抑制破骨细胞、促进成骨细胞的活性来阻止骨量丢失、提高骨密度。 骨质疏松治…

vue-组件生命周期+网络请求

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue-组件生命周期网络请求 目录 组件生命周期 1. Vue的生命周期 2. Vue 子组件和父组件执行顺序…

电脑集中管理软件有哪些?电脑集中管控怎么做

电脑集中管理软件有哪些&#xff1f;电脑集中管控怎么做 电脑集中管理软件是指通过一种软件或系统&#xff0c;对多台电脑进行集中管理和控制的工具。这种软件通常具备远程控制、软硬件监控、自动部署等功能。可以方便企业或组织统一管理电脑资源&#xff0c;提高工作效率。今…

vue的常用指令

1.使用双花括号( {{}} )对变量输出,内部可以写简单的表达式用于对数据的处理 2..v-text&#xff1a;相当于js的innerText, 3.v-html&#xff1a;相当于js的innerHTML 4.v-bind&#xff1a;动态绑定属性,简写是冒号( : ) 5.绑定class&#xff1a;操作元素的 class 列表和内联样式…

【开源】基于Vue和SpringBoot的固始鹅块销售系统

项目编号&#xff1a; S 060 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S060&#xff0c;文末获取源码。} 项目编号&#xff1a;S060&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固…

C语言每日一题(31)相交链表

力扣160.相交链表 题目描述 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意…

【unity2021.3.6f】运行官方 Vuforia Hololens 2 Sample 教程

文章目录 前言一、创建unity项目二、导入unity1.添加到我的资源2.在package Manage 里面去找到&#xff0c;点击下载&#xff0c;下载完成后点击Import 如下图&#xff1a;3.导入途中会有窗口弹出 很多提示&#xff0c;都点击默认选项&#xff1a;Import 、Install/Upgrade 等 …

认识“协议”

文章目录&#xff1a; 什么是协议结构化的数据传输序列化和反序列化网络版本计算器 什么是协议 在计算机网络中&#xff0c;协议是指在网络中进行通信和数据交换时&#xff0c;双方遵循的规则和约定集合。它定义了数据的传输格式、顺序、错误处理、认证和安全性等方面的规范。 …

2018年五一杯数学建模C题江苏省本科教育质量综合评价解题全过程文档及程序

2019年五一杯数学建模 C题 江苏省本科教育质量综合评价 原题再现 随着中国的改革开放&#xff0c;国家的综合实力不断增强&#xff0c;中国高等教育发展整体已进入世界中上水平。作为一个教育大省&#xff0c;江苏省的本科教育发展在全国名列前茅&#xff0c;而江苏省13个地级…

openldap-sasl身份认证镜像

背景 在这篇文章中&#xff0c;AD域信息同步至openLDAP我们使用了SASL将身份验证从OpenLDAP委托给AD”这种方案&#xff0c;本文主要来构建此方案的docker镜像。 sasl官网&#xff1a;Cyrus SASL bitnami/openldap镜像地址&#xff1a;containers/Dockerfile bitnami/openl…

修改服务器端Apache默认根目录

目标&#xff1a;修改默认Apache网站根目录 /var/www/html 一、找到 DocumentRoot “/var/www/html” 这一段 apache的根目录&#xff0c;把/var/www/html 这个目录改 #DocumentRoot "/var/www/html" DocumentRoot "/home/cloud/tuya_mini_h5/build" 二、…

图论| 827. 最大人工岛 127. 单词接龙

827. 最大人工岛 题目&#xff1a;给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。返回执行此操作后&#xff0c;grid 中最大的岛屿面积是多少&#xff1f; 岛屿 由一组上、下、左、右四个方向相连的 1 形成。 题目链接&#xff1a;[827. 最大人工岛](ht…