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

Leetcode热题100:图论

Leetcode 200. 岛屿数量

深度优先搜索法:

对于这道题来说,是一个非常经典的图的问题,我们可以先从宏观上面来看问题,也就是说在不想具体算法的前提下,简单的说出如何找到所有的岛屿呢?

如图中所示,首先非常显而易见的要素就是我们一定要遍历图中的每一个坐标,这是肯定的,然后呢对于岛屿的数量,一开始想的肯定就是每当我们访问了一个1的坐标时,我们就找到了一个岛屿,可是因为我们要遍历整个图,所以肯定不能每次遇到一个1就对岛屿的数量进行增加,因为题目说了,横纵连接着的坐标都是1的话都属于同一个岛屿,就像上图一样证明我们只有三个岛屿

那么我们是不是可以像一个办法,当我们找到了一个岛屿的坐标后,把属于这个坐标的岛屿的其他所有值为1的坐标都记录下来,这样以来,意思就是说在我们继续遍历的时候,我们检查每一个坐标时,如果发现这个坐标已经被标记过了,证明他并不是一个新的岛屿而是一个之前就发现过的岛屿的一部分那么就可以了

如何去实现这个标记的方法呢,就可以用到我们的深度优先搜索,从新发现的坐标开始一直找,直到找到了岛屿的边缘或者整个图的边缘之后返回,这样就能找到所有属于相同岛屿的坐标,那么我们可以把主代码写出来了已经

class Solution:def numIslands(self, grid: List[List[str]]) -> int:res = 0# iterate to check every box in the grid to see# if it is a start for a new lslandfor r in range(len(grid)):for c in range(len(grid[0])):# if so, run a dfs to mark all its fellow# box and add the 1 to the resultif grid[r][c] == '1':dfs(grid, r, c)res = res + 1return res

主体部分的代码非常简单,然后呢我们需要做的就是对于dfs的编写,正如在这个主体代码中写的,你会发现我这里还是用的如果box中存的元素是1,那就最终要增加岛屿数量,这难道不是错的吗?其实这里就隐喻了我们是如何完成对一个岛屿上所有的box进行标记的,与其新建一个空间例如集合然后把dfs中搜索到的box全都加入进去然后每一次循环遍历的时候去看当前的box是否在那个集合中,更好的方法其实就是直接原地更改我们的grid,将搜索到的box中的值从1修改到2,这样这个主体函数中的if 语句就不会被execute了

class Solution:def numIslands(self, grid: List[List[str]]) -> int:def dfs(grid, r, c):# base case, do nothing when we# reached the edge of entire grid or found waterif not (0 <= r < len(grid) and 0 <= c < len(grid[0])) or grid[r][c] != '1':return# mark the visited box as 2grid[r][c] = '2'# call the recursive case on each direction from current boxdfs(grid, r - 1, c)dfs(grid, r + 1, c)dfs(grid, r, c - 1)dfs(grid, r, c + 1)res = 0# iterate to check every box in the grid to see# if it is a start for a new lslandfor r in range(len(grid)):for c in range(len(grid[0])):# if so, run a dfs to mark all its fellow# box and add the 1 to the resultif grid[r][c] == '1':dfs(grid, r, c)res = res + 1return res

这样你就有了整个的代码,其实这种类型的深度优先搜索可以参考我们在二叉树的时候是怎么做的,无非也是一直遍历然后直到我们reach 到了leaf node然后发现新的node是空的时候就直接return,这里不过是多加了两个方向,在二叉树里的recursive case是对左右子节点继续call,这里是对上下左右四个横纵坐标的方向继续call,然后呢条件多加了一个,这里对应的不能超出边界就是二叉树中的if not root, 只是这里还要保证grid[r][c] == 1,不是1的话就不是我们要找的同一个岛屿上的点

时间复杂度 O(m*n):m和n就是grid的长和宽,因为我们要遍历每一个坐标

空间复杂度 O(m*n):在最坏的情况下,如果左上角的box就是陆地1,并且整张图都是1,                                       那么我们就要把每一个box都有一个recursive function,这样在就会用                                     到一个大小为m*n的栈


Leetcode 994. 腐烂的橘子

广度优先搜索法:

这道题的关键在于我们在一开始所给的grid里面存在多个橘子的可能,我们需要在把能弄腐烂的橘子全部弄完之后就返回结果,所以每一分钟里我们需要对所有当前的橘子进行扩散,这里运用深度优先的递归就很麻烦,因为我们每一次逻辑要处理多个搜索

这里我们就使用广度优先,利用队列来对腐烂橘子进行保存并且通过出队来进行遍历然后扩散后把新的腐烂的橘子继续加入队列

这样以来,每一次我们通过向四个方向的检查中发现新的好橘子之后就可以立马对其进行操作,具体分三步,第一步将其加入我们的队列代表下一轮遍历的时候,他会pop出来作为新的坐标然后向四周扩散,第二步将我们的好橘子的count做一个递减,第三步,将grid中其坐标位置的值从1变成2避免后序的遍历中反复visit这个坏橘子

class Solution:def orangesRotting(self, grid: List[List[int]]) -> int:# we are using a queue to do the bfsq = deque()fresh_count = 0res = 0# loop through the gird first to find # the amount of fresh and add the rotten to# the queuefor i in range(len(grid)):for j in range(len(grid[0])):if grid[i][j] == 1:fresh_count = fresh_count + 1elif grid[i][j] == 2:q.append((i, j))# loop until we have no more rotten orangewhile q and fresh_count > 0:# every time we start pop out q again, we did another searchres = res + 1# for each rotten orango, pop them outfor _ in range(len(q)):box = q.popleft()r, c = box[0], box[1]# check topif r - 1 >= 0 and grid[r - 1][c] == 1:fresh_count = fresh_count - 1q.append((r - 1, c))grid[r - 1][c] = 2# check rightif c + 1 < len(grid[0]) and grid[r][c + 1] == 1:fresh_count = fresh_count - 1q.append((r, c + 1))grid[r][c + 1] = 2# check botif r + 1 < len(grid) and grid[r + 1][c] == 1:fresh_count = fresh_count - 1q.append((r + 1, c))      grid[r + 1][c] = 2# check leftif c - 1 >= 0 and grid[r][c - 1] == 1:fresh_count = fresh_count - 1q.append((r, c - 1))grid[r][c - 1] = 2# we did not get them all rottonif fresh_count > 0:return -1else:return res

时间复杂度 O(m*n):m和n就是grid的长和宽,因为我们要遍历每一个坐标

空间复杂度 O(m*n):在最坏的情况下,一开始所有的橘子都是坏橘子,我们使用的额外空间队列的长度最大就是m*n

相关文章:

Leetcode热题100:图论

Leetcode 200. 岛屿数量 深度优先搜索法&#xff1a; 对于这道题来说&#xff0c;是一个非常经典的图的问题&#xff0c;我们可以先从宏观上面来看问题&#xff0c;也就是说在不想具体算法的前提下&#xff0c;简单的说出如何找到所有的岛屿呢&#xff1f; 如图中所示&#x…...

刚进公司第一天-电脑环境搭建

写在前面 之前在公司做过一次开发小工具的分享&#xff0c;这两天有个同事找我学习一些小工具开发的知识&#xff0c;但是我发现他的基础是真的差&#xff0c;想学开发知识却连自己本地电脑环境都没弄好&#xff0c;确实&#xff0c;有些人工作了很久&#xff0c;由于自己工作中…...

kubernetes集群报 unable to load bootstrap kubeconfig处置思路

一.现状和问题现象 公司kubernetes集群是通过kubeadm工具安装的&#xff0c;使用1年之后证书到期。在 kubernetes control plane maste节点服务器上运行 kubeadm certs renew all 命令更新证书后&#xff0c;kubelet 无法正常启动&#xff0c;报错日志如下 Failed to run kube…...

MacBook远程桌面Windows使用Microsoft Remote Desktop for Mac_亲测使用

MacBook远程桌面Windows使用Microsoft Remote Desktop for Mac_亲测使用 像Windows上有自带的远程桌面连接软件.MacBook没有自带的远程连接Windows桌面的工具,需要安装软件来实现. 像远程桌面控制软件一般有 TeamViewer、向日葵远程控制, ToDesk, Microsoft Remote Desktop f…...

Huggingface 笔记:大模型(Gemma2B,Gemma 7B)部署+基本使用

1 部署 1.1 申请权限 在huggingface的gemma界面&#xff0c;点击“term”以申请gemma访问权限 https://huggingface.co/google/gemma-7b 然后接受条款 1.2 添加hugging对应的token 如果直接用gemma提供的代码&#xff0c;会出现如下问题&#xff1a; from transformers i…...

WebGL 理论基础 01 WebGL 基础概念

WebGL 理论基础 基础概念 WebGL 基础概念 顶点着色器的作用是计算顶点的位置。根据计算出的一系列顶点位置&#xff0c;WebGL可以对点&#xff0c; 线和三角形在内的一些图元进行光栅化处理。当对这些图元进行光栅化处理时需要使用片段着色器方法。 片段着色器的作用是计算…...

Leetcode 28:找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 示例 1&#xff1a; 输入&#xff1a;haystack &q…...

docker opensearch arm64 运行失败解决方案

opensearch版本 2.1.0 docker日志错误信息&#xff1a; Disabling execution of install_demo_configuration.sh for OpenSearch Security Plugin Enabling OpenSearch Security Plugin Killing opensearch process 10 OpenSearch exited with code 143 Performance analyze…...

C#、ASP、ASP.NET、.NET、ASP.NET CORE区别、ASP.NET Core其概念和特点、ASP.NET Core个人心得体会

C#是一种面向对象的编程语言&#xff0c;主要用于开发跨平台的应用程序。它是.NET框架的一部分&#xff0c;并且可以在.NET平台上运行。 ASP&#xff08;Active Server Pages&#xff09;是一种用于构建动态Web页面的技术&#xff0c;使用VBScript或JScript作为服务器端脚本语…...

SpringMVC 简介及入门级的快速搭建详细步骤

MVC 回顾 MVC&#xff0c;即Model-View-Controller&#xff08;模型-视图-控制器&#xff09;设计模式&#xff0c;是一种广泛应用于软件工程中&#xff0c;特别是Web应用开发中的架构模式。它将应用程序分为三个核心组件&#xff1a; Model&#xff08;模型&#xff09;&#…...

Flutter编译卡在Running Gradle task ‘assembleDebug

1、翻墙 2、修改国内镜像源&#xff08;以下以Flutter 3.19.3版本为例&#xff09; 找到Flutter SDK目录下的Flutter配置文件resolve_dependencies.gradle 路径&#xff1a;flutter/packages/flutter_tools/gradle/resolve_dependencies.gradle 1)、第一处修改&#xff1a; g…...

基于springboot的牙科就诊管理系统

技术&#xff1a;springbootmysqlvue 一、系统背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。这样…...

C语言 指针练习

一、 a、b是两个浮点型变量&#xff0c;给a、b赋值&#xff0c;建立两个指针分别指向a的地址和b的地址&#xff0c;输出两个指针的值。 #include<stdio.h> int main() {float a,b,*p1,*p2;a10.2;b2.3;p1&a;p2&b;printf("a%f,b%f\n",a,b);printf("…...

【力扣 TOP100】 无重复字符的最长子串

题目描述&#xff1a; 思路&#xff1a; 使用left和right表示子串的端点。每次判断新的right是否在之前的子串里&#xff0c;如果在&#xff0c;则将left更新为新字符在子串里的位置&#xff08;因为在此之间&#xff0c;没有更长的子串了&#xff09;。如果不在则right1&…...

K8S node磁盘清理

K8S磁盘清理 K8S的部署形式相比传统非容器部署&#xff0c;会消耗更多的磁盘&#xff0c;在运行时可能会把磁盘占满。 这里以使用containerd运行时的K8S node为例&#xff0c;说明磁盘会用到那里了和如何清理磁盘 通用处理 磁盘清理: du -h --max-depth6 / 2>/dev/nul…...

2024年上半年软考,现在开始学真的来得及吗?

24上软考报名进行时&#xff0c;如果从现在开始学习来得及吗&#xff1f;只为拿证&#xff0c;还没报名的选哪科通过率高一点呢&#xff1f; 01、现在开始学来得及吗&#xff1f; 还没开始备考的考生&#xff0c;现在开始抓紧时间学还来得及&#xff0c;但是要正视软考的试题…...

SfM——八点法计算F矩阵(基础矩阵)与三角测量

1 八点法计算F矩阵&#xff08;基础矩阵&#xff09; 基础矩阵用于描述两个视图之间的几何关系 基础矩阵&#xff1a;基础矩阵 F F F 是描述两个视图之间相机投影关系的矩阵。对于两个对应的图像坐标点 ( x , y , 1 ) (x, y, 1) (x,y,1) 和 ( u , v , 1 ) (u, v, 1) (u,v,1…...

分布式事务的解决方案--Seata架构

一、Seata的XA模式 二、AT模式原理 三、TCC模式原理 四、MQ分布式事务 异步&#xff0c;非实时&#xff0c;实现最终的一致性。 四、分布式事务的解决方案...

【 React 】React JSX 转换成真实DOM的过程?

1. 是什么 react通过将组件编写的JSX映射到屏幕&#xff0c;以及组件中的状态发生了变化之后React会将这些「变化」更新到屏幕上 在前面文章了解中&#xff0c;JSX通过babel最终转化成React.createElement这种形式&#xff0c;例如&#xff1a; <div>< img src"…...

[Open3d]: 知识记录

python api 官方手册&#xff1a;http://www.open3d.org/docs/release/ 可视化&#xff1a;http://www.open3d.org/docs/release/tutorial/visualization/visualization.html python-vis 参考代码&#xff1a;https://github.com/isl-org/Open3D/tree/master/examples/python/v…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...