《程序员面试金典(第6版)》面试题 16.19. 水域大小(深度优先搜索,类似棋盘类问题,八皇后的简化版本,C++)

news2025/4/28 10:52:34

题目描述

你有一个用于表示一片土地的整数矩阵land,该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小,返回值需要从小到大排序。

示例:

输入:
[
  [0,2,1,0],
  [0,1,0,1],
  [1,1,0,1],
  [0,1,0,1]
]
输出: [1,2,4]

提示:

  • 0 < len(land) <= 1000
  • 0 < len(land[i]) <= 1000

原题链接

解题思路与代码

首先,这道题是一道有意思的思考题,有点类似于棋盘类的题型了。

一上来大家可能有点懵,但是仔细想想或者看过题目下面的相关提示后,可能就会想,哦,这道题我们可以用深度优先搜索去做呀~

其实在做这道题的过程中,我感觉这道题可以算是一道类似棋盘类的问题了,可以说可以算是八皇后的简单版本。因为我们同样要去设置一个标记数组,去记录某一个格子是否已经被记录过了。也要检查多个方向等。

言归正传,让我们来讲解一下这道题到底是如何用深度搜索做的。

  • 首先让我们创建一个记录结果的数组,result,一个二维标记数组visit。
  • 准备好之后,我们开始用双层for循环,从左到右从上到下的去遍历每一个棋子。
  • 只有当这个棋子在land中被记录为0,并且没有被标记数组标记过,我们才能进入这个棋子的递归。
  • 这个递归函数会检查一个棋子的8个方向上都有没有池塘,如果有,则标记这个棋子,最后返回一个int值,代表这个池塘有多少块水域。
  • 我们会把这个池塘添加到result中去,最后把result排个序,之后返回就可以了。

具体代码如下:

class Solution {
public:
    vector<int> pondSizes(vector<vector<int>>& land) {
        vector<int> result;
        int m = land.size();
        int n = land[0].size();
        vector<vector<bool>> visit(m,vector<bool>(n,false));
        for(int i = 0; i < m; ++i)
            for(int j = 0; j < n; ++j)
                if(land[i][j] == 0 && !visit[i][j]){
                    int size = dfs(land,visit,i,j);
                    result.push_back(size);
                }
        sort(result.begin(),result.end());
        return result;
    }
    int dfs(vector<vector<int>>& land, vector<vector<bool>>& visit,int i, int j){
        if(i < 0 || j < 0 || i >= land.size() || j >=land[0].size() || land[i][j] != 0 || visit[i][j])
            return 0;
        int size = 1;
        visit[i][j] = true;
        for(int r = -1; r <= 1; ++r)
            for(int c = -1; c <= 1; ++c)
                size += dfs(land,visit,i + r,j + c);
        return size;
    }
};

在这里插入图片描述

复杂度分析

时间复杂度:

  • 在最坏的情况下,我们需要遍历土地矩阵中的每个单元格,并可能需要进行深度优先搜索。因此,时间复杂度为O(n^2)。

空间复杂度:

  • 我们需要一个与土地矩阵大小相同的visited矩阵来跟踪每个单元格是否已被访问。此外,由于我们使用了递归,因此还需要考虑调用堆栈的空间。在最坏的情况下,可能需要进行m*n次递归调用(例如,当所有单元格都是水域时)。因此,空间复杂度也为O(n^2)。

当我们说深度优先搜索的时间复杂度是O(n^2)时,我们是指最坏的情况下,我们需要访问土地矩阵中的每一个单元格。在这个过程中,每个单元格可能会被DFS函数访问多次(最多9次,包括自身和周围的8个邻居),但是每个单元格只会被处理(即被加入到某个池塘的大小中)一次,因为一旦一个单元格被处理,我们就会将其标记为已访问,之后就不会再处理它了。

因此,虽然DFS函数可能会被调用多于n^2 次,但是我们只需要进行n^2 次实际的处理,所以时间复杂度仍然是O(n^2)。

总结

  • 这道题目主要是为了考察求解者对深度优先搜索(DFS)和图遍历的理解和应用能力。

  • 在实际应用中,这种类型的问题可能出现在一些地理信息系统(GIS)或者环境科学的领域,比如:

    • 水体识别和测量:这个问题可以用于识别和测量地图上的水体。给定一张地形图(通过海拔高度表示),我们可以计算出地图上水体(海拔高度为0的区域)的数量和大小。

    • 连通区域识别:在计算机视觉或图像处理中,这个问题可以用于识别图像中的连通区域。例如,我们可以使用类似的方法来识别和测量图像中的特定颜色或纹理的区域。

    • 地图路径规划:这个问题也可以用于规划地图上的路径。例如,我们可以使用DFS来寻找从一点到另一点的路径,或者寻找所有可以到达的点。

通过这道题,你可以加深对深度优先搜索(DFS)算法的理解,这对于很多图论问题和搜索问题的解决都是非常有帮助的。

最后的最后,如果你觉得我的这篇文章写的不错的话,请给我一个赞与收藏,关注我,我会继续给大家带来更多更优质的干货内容

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

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

相关文章

【数据结构与算法】图的遍历与拓扑排序

文章目录 一、用数组模拟邻接表二、图的深度优先遍历&#xff08;dfs&#xff09;2.1 概念2.2 例题&#xff1a;树的重心 三、图的广度优先遍历&#xff08;bfs&#xff09;3.1 概念3.2 例题&#xff1a;图中点的层次 四、拓扑排序4.1 概念4.2 例题&#xff1a;有向图的拓扑序列…

2直接连接的网络与VLAN划分-2.2【实验】【计算机网络】

2直接连接的网络与VLAN划分-2.2-2.3【实验】【计算机网络】 前言推荐2直接连接的网络与VLAN划分2.1共享式以太网和交换式以太网2.2交换机MAC地址表建立与帧转发实验目的实验内容及实验环境实验原理交换机通过逆向学习帧的源地址&#xff0c;构建MAC地址表;交换机中MAC地址的构建…

netty基础(五)

1.基本介绍 1>.异步的概念和同步相对.当一个异步过程调用发出后,调用者不能立刻得到结果.实际处理这个调用的组件在完成后,通过状态、通知和回调来通知调用者; 2>.Netty中的I/O操作是异步的,包括Bind、Write、Connect等操作会简单的返回一个 ChannelFuture; 3>.调用…

二、Eureka注册中心

目录 注册中心主要有三种角色&#xff1a; 1、服务提供者&#xff08;RPC Server&#xff09; 2、服务消费者&#xff08;RPC Client&#xff09; 3、服务注册中心&#xff08;Registry&#xff09; 注册中心实现原理 常用的注册中心&#xff1a; 常用注册中心对比&…

【C/C++每日一练】总目录(更新至2023.5.12)

C/C 2023.05 2023.5.11-2023.5.12 20230512 1. 成绩打印 ※ 2. 按要求补齐数组 &#x1f31f;&#x1f31f;&#x1f31f; 3. 水仙花数 ※ 20230511 1. 最长公共前缀 &#x1f31f; 2. 打家劫舍 &#x1f31f;&#x1f31f; 3. 最接近的三数之和 &#x1f31f;&am…

修改通过CDH安装的Kafka和Zookeeper等组件的最大文件句柄数

目录 1.查看当前kafka最大文件句柄数 2.修改supervisord.service 服务配置文件 3.加载配置文件 4.重启supervisord.service服务 5.重启kafka等组件 6.查看修改后最大文件句柄数 7.查看kafka当前使用的文件句柄数 参考&#xff1a; 1.查看当前kafka最大文件句柄数 jpsc…

【rust】| 05——语法基础 | 流程控制

系列文章目录 【rust】| 00——开发环境搭建 【rust】| 01——编译并运行第一个rust程序 【rust】| 02——语法基础 | 变量(不可变?)和常量 【rust】| 03——语法基础 | 数据类型 【rust】| 04——语法基础 | 函数 【rust】| 05——语法基础 | 流程控制 文章目录 流程控制1. 条…

双向链表的功能实现

前言&#xff1a;我们已经学习并知道了单链表的实现&#xff0c;链表的实现方式不只是单链表一种&#xff0c;今天我们就来介绍一种新的结构&#xff0c;就是双链表结构&#xff0c;本质上是将节点间进行双向链接&#xff0c;从而使一些操作更加容易实现。 目录 1.双向链表的简…

OpenCL编程指南-3.3类型转换

隐式类型转换 隐式类型转换是一种自动的类型转换&#xff0c;只要混合使用不同的类型&#xff0c;编译器就会完成这种隐式类型转换。这里支持表4-1中定义的标量类型&#xff08;除void、double和half以外&#xff09;的隐式转换。完成隐式转换时&#xff0c;并不只是重新解释一…

MySQL:数据库的增删查改

我们这一篇主要介绍数据库的增删查改~ 增&#xff1a;insert into 表名 value (); 删&#xff1a;delete from 表名; 查&#xff1a;select from 表名; 改&#xff1a;update 表名; 目录 1.insert&#xff08;增&#xff09; 2.select&#xff08;查询&#xff09; 2.1 全列…

Goby 漏洞更新 |Telesquare TLR-2005Ksh 路由器 ExportSettings.sh 文件下载漏洞(CVE-2021-46423)

漏洞名称&#xff1a;Telesquare TLR-2005Ksh 路由器 ExportSettings.sh 文件下载漏洞&#xff08;CVE-2021-46423&#xff09; English Name&#xff1a;Telesquare TLR-2005Ksh ExportSettings.sh file download (CVE-2021-46423) CVSS core: 7.5 影响资产数&#xff1a;2…

勒索病毒“顽疾”,没有“特效药”吗?

基础设施瘫痪、企业和高校重要文件被加密、毕业论文瞬间秒没……这就是六年前的今天&#xff0c;WannaCry勒索攻击爆发时的真实场景。攻击导致150多个国家数百万台计算机受影响&#xff0c;也让勒索病毒首次被全世界广泛关注。 六年后&#xff0c;勒索攻击仍是全球最严重的网络…

bootp引导程序协议

bootp又称为引导程序协议,我们来简单了解一下这个协议以及他的用法。 1&#xff0c;BOOTP 请求和应答均被封装在 U D P数据报中 &#xff1b; 2&#xff0c;B O O T P使用 U D P&#xff0c;且通常需与 T F T P协同工作&#xff1b; 3&#xff0c;B O O T P有两个熟知端口&a…

选择合适的 MQTT 云服务:一文了解 EMQX Cloud Serverless、Dedicated 与 BYOC 版本

引言 EMQX Cloud 是基于 EMQX Enterprise 构建的一款全托管云原生 MQTT 消息服务。为了满足不同客户的需求&#xff0c;EMQX Cloud 提供了三种版本供客户选择&#xff1a;Serverless 版、专有版和 BYOC 版。 本文将简要介绍这三个版本的核心区别&#xff0c;并通过三个用户故…

【ChatGPT】体验一下ChatGPT

体验一下ChatGPT 可以帮你写代码、写邮件、编故事的神器 最近OpenAI 发布了备受期待的原型通用 ChatGPT&#xff0c;这是一种基于对话的 AI 聊天界面&#xff0c;算是GPT-3(Generative Pre-trained Transformer 3)的继承者&#xff0c;今天记录一下体验的过程&#xff0c;以前…

详解set/map的底层结构——AVL树和红黑树

目录 前文 一&#xff0c;AVL树 1.1 什么是AVL树&#xff1f; 1.2 AVL树节点的定义 1.3 insert—插入(重点) 1.4 旋转(重点) 1.4.1 右单旋 1.4.2 左单旋 1.4.3 左右双旋 1.4.4 右左双旋 1.5 IsBalanc(平衡判断) 1.6 中序遍历 1.7 测试 二&#xff0c;红黑树 2.1 什么…

非常提效的7款原型工具推荐

原型图工具允许在开发前进行测试和迭代过程&#xff0c;可以帮助节省大量的开发时间和成本。在本文中&#xff0c;我们盘点了7个易于使用的原型图工具&#xff0c;以提高您的生产力&#xff01; 1.即时设计 即时设计是一款免费的在线 UI 设计工具&#xff0c;无系统限制&…

自学黑客,一般人我劝你还是算了吧!

我为啥说自学黑客&#xff0c;一般人我还是劝你算了吧&#xff01;因为我就是那个不一般的人。 首先我谈下对黑客&网络安全的认知&#xff0c;其实最重要的是兴趣热爱&#xff0c;不同于网络安全工程师&#xff0c;他们大都是培训机构培训出来的&#xff0c;具备的基本都是…

【Python入门】Python的判断语句(if elif else语句)

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于Python零基础入门系列&#xff0c;本专栏主要内容为Python基础语法、判断、循环语句、函…

从0开始学习数据库

一个数据库最重要的部分是什么&#xff1f; 关系型数据库mysql有着四大特性&#xff0c;原子性&#xff0c;隔离性&#xff0c;一致性&#xff0c;持久性。 kv数据库有着原子性&#xff0c;持久性&#xff0c;弱一致性。 可见&#xff0c;不管数据库的存储引擎是什么&#xff0…