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 lsland
        for 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 result
                if grid[r][c] == '1':
                    dfs(grid, r, c)
                    res = res + 1
        
        return 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 water
            if not (0 <= r < len(grid) and 0 <= c < len(grid[0])) or grid[r][c] != '1':
                return
            
            # mark the visited box as 2
            grid[r][c] = '2'

            # call the recursive case on each direction from current box
            dfs(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 lsland
        for 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 result
                if grid[r][c] == '1':
                    dfs(grid, r, c)
                    res = res + 1
        
        return 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 bfs
        q = deque()
        fresh_count = 0
        res = 0

        # loop through the gird first to find 
        # the amount of fresh and add the rotten to
        # the queue
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1:
                    fresh_count = fresh_count + 1
                elif grid[i][j] == 2:
                    q.append((i, j))


        # loop until we have no more rotten orange
        while q and fresh_count > 0:

            # every time we start pop out q again, we did another search
            res = res + 1

            # for each rotten orango, pop them out
            for _ in range(len(q)):
                box = q.popleft()
                r, c = box[0], box[1]

                # check top
                if r - 1 >= 0 and grid[r - 1][c] == 1:
                    fresh_count = fresh_count - 1
                    q.append((r - 1, c))
                    grid[r - 1][c] = 2

                
                # check right
                if c + 1 < len(grid[0]) and grid[r][c + 1] == 1:
                    fresh_count = fresh_count - 1
                    q.append((r, c + 1))
                    grid[r][c + 1] = 2
                
                # check bot
                if r + 1 < len(grid) and grid[r + 1][c] == 1:
                    fresh_count = fresh_count - 1
                    q.append((r + 1, c))      
                    grid[r + 1][c] = 2

                # check left
                if c - 1 >= 0 and grid[r][c - 1] == 1:
                    fresh_count = fresh_count - 1
                    q.append((r, c - 1))
                    grid[r][c - 1] = 2
        
        # we did not get them all rotton
        if fresh_count > 0:
            return -1
        else:
            return res

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在 MacOS 中安装

查看&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;在基于 Android 相机预览的 CV 应用程序中使用 OpenCL 下一篇&#xff1a;基于ARM 的Linux系统的交叉编译 以下步骤已针对 MacOSX &#xff08;Mavericks&#xff09; 进行了…

NEC 78K系列MCU概述

一.初识 NEC MCU NEC&#xff0c;即日本电气株式会社&#xff0c; 经营半导体业务。 NEC 倡导“ ALL Flash”&#xff0c;即 MCU 内的程序存储器使用 Flash ROM。 为什么用 Flash ROM&#xff1f; 与掩膜 ROM 微控制器相比&#xff0c; Flash 微控制器加速了系…

开源表单设计器颗粒度级别控制表单的显示条件原理分析

表单渲染中, 有些表单的显示有不同条件, 比如需要上一个表单的开关打开,或者文本内容为 xxxx, 或者需要大于或等于或小于指定值, 或者需要选中某个选项, 或者需满足以上多个条件或在满足多个条件中的一个, 有 n 种场景选择, 这样就需要条件显示配置功能, 来满足多样化需求 预览…

【Django实战一】创建新项目

一、新建Project django-admin startproject 项目名称二、创建应用 1、创建应用 python manage.py startapp 应用名称应用创建后&#xff0c;项目的根目录下会生成对应应用名称的文件夹 2、注册应用 新创建的应用需要在settings.py中的INSTALLED_APPS中注册该应用 INSTALL…

Prompt-RAG:在特定领域中应用的革新性无需向量嵌入的RAG技术

论文地址&#xff1a;https://arxiv.org/ftp/arxiv/papers/2401/2401.11246.pdf 原文地址&#xff1a;https://cobusgreyling.medium.com/prompt-rag-98288fb38190 2024 年 3 月 21 日 虽然 Prompt-RAG 确实有其局限性&#xff0c;但在特定情况下它可以有效地替代传统向量嵌入 …

KW音乐搜索参数

声明&#xff1a; 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 逆向目标: …

基于SpringBoot+Layui的社区物业管理系统

项目介绍 社区物业管理系统是基于java程序开发,本系统分为业主和管理员两个角色 业主可以登陆系统,查看车位费用信息,查看物业费用信息,在线投诉,查看投诉,在线报修; 管理员可以车位收费信息,物业收费信息,投诉信息,楼宇信息,房屋信息,业主信息,车位信息,抄表信…

ArkTS编写的HarmonyOS原生聊天UI框架

简介 ChatUI&#xff0c;是一个ArkTS编写的HarmonyOS原生聊天UI框架&#xff0c;提供了开箱即用的聊天对话组件。 下载安装 ohpm install changwei/chatuiOpenHarmony ohpm 环境配置等更多内容&#xff0c;请参考如何安装 OpenHarmony ohpm 包 接口和属性列表 接口列表 接…

Git、Github、Gitee、GitLab学习,团队协助/版本控制

Git 是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种 项目。B站尚硅谷Git学习笔记 一、Git的常用命令 1.git工作机制 工作区和暂存区的文件都可删除&#xff0c;但是提交到本地库则不可删除&#xff0c;有历史记录 2.历史版本 2.1查…

如何打破SAST代码审计工具的局限性?

关键词&#xff1a;白盒测试&#xff1b;代码分析工具&#xff1b;代码扫描工具&#xff1b;静态代码检测工具&#xff1b; 在代码的世界里&#xff0c;安全问题如同潜伏的暗礁&#xff0c;随时可能让航行中的软件项目触礁沉没。SAST代码审计工具如同雷达一样&#xff0c;以其独…

Doris记录

Doris是一个开源的分布式分析型数据库&#xff0c;最初由阿里巴巴开发并开源&#xff0c;目前隶属于Apache基金会。 Doris基于大规模并行处理&#xff08;MPP&#xff09;架构&#xff0c;提供高性能和实时的数据分析能力。它以极速易用的特点被广泛使用&#xff0c;能够应对高…

探索 PostgreSQL 的外部数据包装器和统计函数

PostgreSQL 因其稳定性和可扩展性而广受青睐&#xff0c;为开发人员和数据管理员提供了许多有用的函数。在这些函数中&#xff0c;file_fdw_handler、file_fdw_validator、pg_stat_statements、pg_stat_statements_info 以及 pg_stat_statements_reset 是其中的重要函数&#x…

鸿蒙Harmony应用开发—ArkTS-全局UI方法(时间滑动选择器弹窗)

以24小时的时间区间创建时间滑动选择器&#xff0c;展示在弹窗上。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 本模块功能依赖UI的执行上下文&#xff0c;不可在UI上下文不明确的地方使用&…

java设计模式--模板方法

在开始模板方法的学习之前&#xff0c;先看下面一段话&#xff1a; 模板&#xff0c;是指作图或设计方案的固定格式。模板是将一个事物的结构规律予以固定化、标准化的成果&#xff0c;它体现的是结构形式的标准化。 ----百度百科 通俗来说&#xff0c;模板其实就是把一个事物的…

前端案例:产品模块

文章目录 产品模块效果结构布局分析父级盒子布局图片和段落评价和详情 产品模块效果 结构布局分析 1、大的父级盒子包含全部的内容 2、内容装入 图片&#xff08;img标签&#xff09;&#xff1b;分别三个子盒子装入两段评价以及商品信息。 父级盒子布局 div {width: 300px…

ChatGPT高效完成简历制作[中篇4]-有爱AI实战教程(十一)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、导读&#xff1a; 在使用 ChatGPT 时&#xff0c;当你给的指令越精确&#xff0c;它的回答会越到位&#xff0c;举例来说&#xff0c;假如你要请它帮忙写文案&#xff0c…

6.2 ServiceNow 自动化测试框架 (ATF) 简介

6.2 自动化测试框架 ATF 简介 目录一、自动化测试框架 (ATF) 简介1. Automated Test Framework&#xff08;ATF&#xff09;2. 使用自动化测试框架 (ATF)的好处&#xff1a; 二、 ATF的测试类型1. 功能业务逻辑测试2. 回归测试3. 浏览器兼容性测试4. 服务器端 Jasmine测试 三、…

IBM SPSS Statistics for Mac v27.0.1中文激活版

IBM SPSS Statistics for Mac是一款功能强大的统计分析软件&#xff0c;专为Mac用户设计&#xff0c;用于数据分析和决策支持。该软件拥有直观易用的界面和丰富多样的统计工具&#xff0c;使得用户可以轻松进行数据处理、分析和解释。 软件下载&#xff1a;IBM SPSS Statistics…

JQuery EasyUI DataGrid行添加水印

代码 css: .water-mark::after {content: 有异议;position: absolute;left: 460px;top: 40px;color: rgb(255 0 0);transform: rotate(-25deg);pointer-events: none;z-index: 10;} js: $(#dgData).datagrid({loadMsg: 数据加载中&#xff0c;请稍后……,// fitColumns: true,…

使用工具类简单快速导出复杂的Excel,以及下载Excel 模板

Gitee 地址如下&#xff1a; https://gitee.com/xia-lijun/export-Excel.githttps://gitee.com/xia-lijun/export-Excel.git 一&#xff1a;首先引入pom.xml 依赖 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifact…