岛屿周长问题的三种解法:直接计数法、数学计算法与深度优先搜索

问题描述

给定一个二维网格 grid,其中1表示陆地,0表示水域。网格中的格子水平和垂直方向相连(对角线不相连)。网格中恰好有一个岛屿(即一个或多个相连的陆地格子),需要计算这个岛屿的周长。

解法一:直接计数法(迭代法)

思路分析

这是最直观的解法:遍历网格中的每个格子,如果是陆地,初始周长为4。然后检查其上下左右四个方向的相邻格子:

  • 每有一个相邻的陆地格子,周长减1

  • 边界情况自动处理(边界外的格子视为水域)

代码实现

class Solution {
public:int islandPerimeter(vector<vector<int>>& grid) {int res = 0;int m = grid.size(), n = grid[0].size();for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {int add = 4;    // 方格初始周长if(grid[i][j] == 1) {if(i - 1 >= 0 && grid[i - 1][j] == 1) add--; // 上if(i + 1 < m && grid[i + 1][j] == 1) add--;  // 下if(j - 1 >= 0 && grid[i][j - 1] == 1) add--; // 左if(j + 1 < n && grid[i][j + 1] == 1) add--;  // 右res += add;}}}return res;}
};

复杂度分析

  • 时间复杂度:O(mn),其中m和n分别是网格的行数和列数

  • 空间复杂度:O(1),仅使用常数级别的额外空间

解法二:数学计算法

思路分析

这种方法基于一个数学观察:

  1. 每个陆地格子贡献4条边

  2. 每对相邻的陆地格子共享一条边,会使总周长减少2条边

因此,岛屿周长 = 陆地格子数 × 4 - 相邻边数 × 2

代码实现

class Solution {public int islandPerimeter(int[][] grid) {int landCount = 0; // 陆地格子数量int adjacentCount = 0; // 相邻边数量for (int r = 0; r < grid.length; r++) {for (int c = 0; c < grid[0].length; c++) {if (grid[r][c] == 1) {landCount++;// 只检查右侧和下侧,避免重复计数if (c + 1 < grid[0].length && grid[r][c + 1] == 1) {adjacentCount++;}if (r + 1 < grid.length && grid[r + 1][c] == 1) {adjacentCount++;}}}}return landCount * 4 - adjacentCount * 2;}
}

复杂度分析

  • 时间复杂度:O(mn)

  • 空间复杂度:O(1)

解法三:深度优先搜索(DFS)

思路分析

使用深度优先搜索遍历岛屿:

  1. 当从陆地移动到边界或水域时,周长增加1

  2. 使用标记避免重复访问(将访问过的陆地标记为2)

  3. 递归探索四个方向(右、下、左、上)

代码实现

class Solution {constexpr static int dx[4] = {0, 1, 0, -1}; // 右、下、左、上constexpr static int dy[4] = {1, 0, -1, 0};public:int dfs(int x, int y, vector<vector<int>> &grid, int n, int m) {// 遇到边界或水域,贡献1条边if (x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == 0) {return 1;}// 已访问过的陆地,不贡献边if (grid[x][y] == 2) {return 0;}grid[x][y] = 2; // 标记为已访问int res = 0;// 探索四个方向for (int i = 0; i < 4; ++i) {int tx = x + dx[i];int ty = y + dy[i];res += dfs(tx, ty, grid, n, m);}return res;}int islandPerimeter(vector<vector<int>> &grid) {int n = grid.size(), m = grid[0].size();int ans = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (grid[i][j] == 1) {ans += dfs(i, j, grid, n, m);}}}return ans;}
};

复杂度分析

  • 时间复杂度:O(mn),每个格子最多访问一次

  • 空间复杂度:O(mn),递归调用栈的深度在最坏情况下可能达到网格大小

总结与对比

方法优点缺点适用场景
直接计数法直观易懂,实现简单需要检查四个方向小规模网格
数学计算法效率高,仅需遍历一次需要理解数学原理所有规模网格
深度优先搜索符合岛屿遍历的直觉,可扩展性强需要递归,可能栈溢出大规模连通岛屿或需要扩展功能

在实际应用中:

  1. 对于简单场景,数学计算法通常是最优选择,高效且简洁

  2. 当需要扩展功能(如计算多个岛屿)时,DFS更具扩展性

  3. 直接计数法则提供了最直观的实现参考

理解这三种解法的核心思想,能够帮助我们在解决类似网格问题时灵活选择最合适的策略。

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

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

相关文章

将包含父子关系的扁平列表 List<Demo> 转换成树形结构的 List<DemoVO>,每个节点包含自己的子节点列表

1.stream递归操作 private List<DemoVO> createtree(List<Demo> datas) {//得到父节点return datas.stream().filter(m -> TargetConstants.ROOT.equalsIgnoreCase(m.getParentId())).map(m -> {DemoVO vo new DemoVO();vo.setTaxonomyId(m.getPlatformTaxo…

【Jmeter】Jmeter 高并发性能压力测试

目录 一、下载 Jmeter 二、配置环境变量 三、设置中文语言 四、入门最简单的高并发性能压测流程 1. 添加线程组 2. 添加请求 3. 添加监听器 3.1 添加聚合报告 3.2 添加结果树 4. 启动测试 2 种启动方式&#xff1a; 查看结果树&#xff1a; 聚合报告&#xff1a; 五…

芯片测试之VIL/VIH(输入电平)Test全解析:从原理到实战

大家好&#xff0c;我是硅言。在数字芯片的“沟通体系”中&#xff0c;​​VIL&#xff08;输入低电平&#xff09;​​和​​VIH&#xff08;输入高电平&#xff09;​​如同芯片的“听觉阈值”&#xff0c;决定了它能否准确识别外部信号的逻辑状态。本文将从原理剖析、测试方…

【WPF】MVVM的消息机制

在WVM&#xff08;Model-View-ViewModel&#xff09;架构中&#xff0c;消息机制主要用于实现ViewModel与View之间的通信&#xff0c;同时保持它们的分离。这对于维护代码的清晰度和可测试性非常重要。在WPF&#xff08;Windows Presentation Foundation&#xff09;应用程序中…

以楼宇自控关键技术,夯实现代低碳建筑发展重要基础

当“碳达峰、碳中和”成为全球发展共识&#xff0c;建筑行业作为能源消耗与碳排放的重要领域&#xff0c;正加速向低碳化转型。在这场绿色变革中&#xff0c;楼宇自控技术凭借对建筑设备的智能管控与能源优化能力&#xff0c;成为现代低碳建筑建设的核心支撑。从数据采集到智能…

西电【信息与内容安全】课程期末复习笔记

西电【信息与内容安全】课程期末复习笔记 来自2022年春的古早遗留档案&#xff0c;有人需要这个&#xff0c;我就再发一下吧。 ‍ 平时成绩&#xff1a; 10%。线上&#xff1a; 10% &#xff08;线上学习内容&#xff0c; 共 100 分。&#xff09;实验&#xff1a; 10% &#…

【论文阅读笔记】ICLR 2025 | 解析Ref-Gaussian如何实现高质量可交互反射渲染

Reflective Gaussian Splatting Info 会议 【ICLR 2025】 作者 复旦大学&#xff0c;萨里大学&#xff1b;复旦张力教授团队 Github地址 https://github.com/fudan-zvg/ref-gaussian.git Project地址 https://fudan-zvg.github.io/ref-gaussian/ Abstract 新视图合成得益…

面向GPU、CPU及机器学习加速器的机器学习编译器

机器学习编译器概述 机器学习编译器是一种专门针对机器学习工作负载设计的工具&#xff0c;旨在将高层模型描述&#xff08;如TensorFlow或PyTorch模型&#xff09;高效编译为可在不同硬件&#xff08;如GPU、CPU或专用加速器&#xff09;上执行的底层代码。其核心目标是优化计…

论文分类打榜赛Baseline(2):InternLM昇腾硬件微调实践

本文来自社区投稿&#xff0c;作者丁一超 书生大模型实战营第5期已正式启动&#xff0c;本期实战营新增「论文分类打榜赛」&#xff0c;以帮助学员更好地掌握大模型技能。 本文将手把手带领大家如何基于昇腾微调 InternLM 模型&#xff0c;轻松上手论文自动分类任务。从环境配…

mac安装mvnd结合idea

mac安装mvnd结合idea hi&#xff0c;我是阿昌&#xff0c;今天记录一下mac系统下如何安装mvnd同时通过maven-helper插件配置mvnd命令&#xff0c;提升编译速度&#xff1b; 0、前言 如果你正在开发一个由大量模块组成的大型项目&#xff0c;Gradle可以让大型项目构建的更快&…

扩展模块--QWebEngine功能及架构解析

Qt WebEngine 模块在 Qt 6.9 中提供了基于 Chromium 的网页渲染引擎功能。 一、主要功能 核心功能 网页渲染引擎 基于 Chromium 项目的最新稳定版本 支持现代 HTML5、CSS3 和 JavaScript 标准 主要组件 QWebEngineView - 用于显示网页内容的 widget QWebEnginePage - 表示…

Spring Boot Admin监控

1、概述 Spring Boot Admin 是一款用于监控 Spring Boot 应用程序的开源工具&#xff0c;可帮助开发者实时监控应用的运行状态、性能指标、日志信息等。 2、核心功能 应用状态监控 显示应用是否在线、启动时间、运行时长等基础信息。监控 JVM 相关指标&#xff1a;内存使用情…

【QT】QTableView自定义样式:仅显示行间隔、隐藏列间隔、表头样式、表格样式、单行选中等

目录 0.背景 1.详细代码 0.背景 项目需要&#xff0c;我有一个自定义的类Steer_Electrode_Table&#xff0c;是一个QTableView&#xff1b; 记录一下QTableView修改前后的样式&#xff0c;仅供参考 看一下我修改前后的样式对比 1.详细代码 void Steer_Electrode_Table::init…

mvnd-快速打包maven项目

mvnd 一、简介一、定位与背景二、核心架构与加速原理三、使用注意事项 二、下载安装三、idea集成mvnd插件四、打包测试时长 一、简介 mvnd&#xff08;Maven Daemon&#xff09;是Apache Maven团队推出的高性能构建工具&#xff0c;旨在解决传统Maven构建速度慢的问题。它通过…

C++ 中的尾调用优化TCO:原理、实战与汇编分析

C尾调用优化 什么是尾调用&#xff1f;描述无返回值函数最后调用函数也可能做尾调用优化 例子关键特征&#xff08;写法&#xff09; 尾调用和尾递归的区别&#xff1f;为什么尾调用优化可以提高效率&#xff1f;通常的递归调用&#xff1a;尾调用优化&#xff1a;为什么栈帧复…

Java集合 - ArrayList底层源码解析

下面开始对 Java 中 ArrayList 的深度源码分析&#xff0c;基于 JDK 8 的实现&#xff08;后续版本略有差异&#xff0c;但核心逻辑一致&#xff09;。我们将从 类结构、扩容机制、核心方法实现、性能优化、线程安全问题 等角度进行详细解析 一、类结构与核心字段 1. 类继承关…

【Qt】Qt控件

文章目录 Qt控件Layout Spacer垂直布局QVBoxLayout水平排列布局QHBoxLayout网格布局 QGridLayout表格布局 QFormLayout Button Contain命令按钮Push Button工具按钮Tool Button单选按钮Radio Button复选框按钮Check Box命令链接按钮Command Link Button按钮盒Button Box组合框G…

PHP基础-运算符

PHP 的运算符是编程中非常基础但又非常重要的一部分&#xff0c;掌握它们能让你更灵活地处理各种逻辑、计算和流程控制。 算术运算符 用于基本数学运算&#xff1a; 运算符含义示例加法$a $b-减法$a - $b*乘法$a * $b/除法$a / $b%取模$a % $b 示例&#xff1a; <?ph…

AR珠宝佩戴与传统的珠宝购物有哪些区别?​

AR 珠宝佩戴与传统的珠宝购物究竟存在着哪些显著区别呢?在传统的珠宝购物模式里&#xff0c;顾客往往需要花费时间和精力前往实体珠宝店。踏入店内&#xff0c;首先映入眼帘的便是那一排排的玻璃展柜&#xff0c;此时&#xff0c;销售人员会热情地走上前&#xff0c;小心翼翼地…

华为云CAE部署spring cloud服务

1 概述 华为云CAE&#xff08;Cloud Application Engine云应用引擎&#xff09;是一个面向WEB、微服务应用的Serverless托管服务&#xff0c;提供极速部署、极低成本、极简运维的一站式应用托管方案。支持从源码、软件包、镜像包快速发布应用&#xff0c;秒级弹性伸缩、按量付…