【力扣hot100】刷题笔记Day15

news2025/2/25 0:26:58

前言

  • 今天要刷的是图论,还没学过,先看看《代码随想录》这部分的基础

深搜DFS理论基础

  • 深搜三部曲

    • 确认递归函数、参数
    • 确认终止条件
    • 处理目前搜索节点出发的路径
  • 代码框架

    • void dfs(参数) {
          if (终止条件) {
              存放结果;
              return;
          }
      
          for (选择:本节点所连接的其他节点) {
              处理节点;
              dfs(图,选择的节点); // 递归
              回溯,撤销处理结果
          }
      }
      

797. 所有可能的路径 - 力扣(LeetCode)

  • DFS

    • class Solution:
          def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
              res = []   # 存放结果
              path = [0]  # 当前路径
              
              def dfs(root: int):
                  if root == len(graph) - 1:  # 如果到达最后节点存入结果,
                      res.append(path[:])  # path[:]避免使用引用,deep copy
                      return
                  for node in graph[root]:  # 遍历root所有节点
                      path.append(node)     # path加上当前遍历节点
                      dfs(node)             # 下一层继续搜索
                      path.pop()            # 回溯,撤销节点
              
              dfs(0)
              return res
      

广搜BFS理论基础

  • 适用于解决两个点之间的最短路径问题
  • from collections import deque
    dir = [(0, 1), (1, 0), (-1, 0), (0, -1)] # 创建方向元素
    
    def bfs(grid, visited, x, y):
      queue = deque() # 初始化队列
      queue.append((x, y)) # 放入第一个元素/起点
      visited[x][y] = True # 标记为访问过的节点
    
      while queue: # 遍历队列里的元素
        curx, cury = queue.popleft() # 取出第一个元素
        for dx, dy in dir: # 遍历四个方向
          nextx, nexty = curx + dx, cury + dy
          if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]): 
            continue  # 越界了,直接跳过
          if not visited[nextx][nexty]: # 如果节点没被访问过  
            queue.append((nextx, nexty)) # 加入队列
            visited[nextx][nexty] = True # 标记为访问过的节点

 200. 岛屿数量 - 力扣(LeetCode)

  • DFS

    • class Solution:
          def numIslands(self, grid: List[List[str]]) -> int:
              m, n = len(grid), len(grid[0])
              # visited = [[False] * n for _ in range(m)]  # 如果不能修改用标记grid
              # 深搜当前陆地部分
              def dfs(x, y):  # x表示行,y表示列
                  grid[x][y] = "0"  # 遍历到的节点就置为0以防重复,用visited则删除此句
                  for nx, ny in [(x-1,y), (x+1,y), (x,y-1), (x,y+1)]:
                      if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == "1":
                      # if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == "1" and not visited[nx][ny]:
                          # visited[nx][ny] = True
                          dfs(nx,ny)
              # 依次遍历每个节点搜索大陆
              res = 0
              for i in range(m):
                  for j in range(n):
                      if grid[i][j] == "1":
                      # if not visited[i][j] and grid[i][j] == '1':
                          # visited[i][j] = True
                          res += 1  # 遇到没访问过的陆地,+1
                          dfs(i, j)
              # 返回总陆地数
              return res
  •  BFS

    • class Solution:
          def numIslands(self, grid: List[List[str]]) -> int:
              m, n = len(grid), len(grid[0])
              # visited = [[False] * n for _ in range(m)]  # 如果不能修改用visited标记grid中已访问节点
              # 广搜当前陆地部分
              def bfs(x, y):  # x表示行,y表示列
                  q = deque()
                  q.append((x,y))
                  grid[x][y] = "0"  # 遍历到的节点就置为0以防重复,用visited则删除此句
                  # visited[x][y] = True  # 用visited
                  while q:
                      x0, y0 = q.popleft()  # 当前遍历节点加入队列
                      for nx, ny in [(x0-1,y0), (x0+1,y0), (x0,y0-1), (x0,y0+1)]:
                          if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == "1":   # 用visited则删除此句
                          # if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == "1" and not visited[nx][ny]:
                              q.append((nx, ny))
                              grid[nx][ny] = "0"  # 加入列表就标记为访问过,用visited则删除此句
                              # visited[nx][ny] = True  # 用visited                        
              # 依次遍历每个节点搜索大陆
              res = 0
              for i in range(m):
                  for j in range(n):
                      if grid[i][j] == "1":
                      # if not visited[i][j] and grid[i][j] == '1':
                          res += 1  # 遇到没访问过的陆地,+1
                          bfs(i, j)
              # 返回总陆地数
              return res
  • 并查集 

    • 没接触过并查集,依据这道题在B站大学找了相关视频和文章学习一下
    • ## 解法三:UnionFind 并查集经典解法
      class UnionFind: ## 定义为一个类。后面类似的题目,也可以直接搬去使用
          def __init__(self, grid): ## 初始化
              m, n = len(grid), len(grid[0])
              self.count = 0 ## count 是最终结果,初始化为0
              self.parent = [-1] * (m * n)  ## 初始化 parent 数组取值全部为 -1
      
              ## rank 秩,表示树的高度,在连接的时候要规定秩小的指向秩大的元素
              self.rank = [0] * (m * n) ## rank 用来实现上下左右的合并;初始化全部为 0 
              
              ## 计算陆地的总数 count;修改 parent 数组陆地元素的取值
              for i in range(m):
                  for j in range(n):
                      if grid[i][j] == "1": ## 对于陆地元素,把它的parent初始化为它的一维化的位置
                          self.parent[i * n + j] = i * n + j ## parent初始化为元素本身的一维化的(位置)索引
                          self.count += 1  ## 陆地总数
          
          ## find 方法给union 方法调用
          def find(self, i):
              if self.parent[i] != i: ## 对于索引不等于自身的元素
                  self.parent[i] = self.find(self.parent[i]) ## 路径优化。把所有链式关系,简化为一层的父子关系
              return self.parent[i] ## 返回父亲的索引(也等于该索引对应的取值)
          
          ## 最关键是 union 方法,用来处理目标元素并计算岛屿数量
          def union(self, x, y):
              rootx = self.find(x) ## 找到自己的 root 索引
              rooty = self.find(y) ## 找到自己的 root 索引
              if rootx != rooty:  ## 如果不等,则进行合并
                  if self.rank[rootx] <= self.rank[rooty]: ## 如果 rank 更小
                      self.parent[rootx] = rooty  ## 秩小的指向秩大的元素
                  else:
                      self.parent[rooty] = rootx  ## 秩小的指向秩大的元素
      
                  if self.rank[rootx] == self.rank[rooty]: ## 如果秩相等
                      self.rank[rootx] += 1 ## 如果深度相同,新节点的 rank + 1
                  self.count -= 1 ## 合并一次,则陆地数量减一(岛屿数量=陆地数量-总的合并次数)
      
      ## 主类 + 主函数
      class Solution:
          def numIslands(self, grid: List[List[str]]) -> int: ## 主函数
              nr = len(grid) ## number of row
              if nr == 0:
                  return 0
              nc = len(grid[0]) ## number of column
      
              uf = UnionFind(grid) ## 调用并查集函数
      
              ## 遍历每一个位置
              for r in range(nr):
                  for c in range(nc):
                      if grid[r][c] == "1": ## 碰到陆地 1
                          grid[r][c] = "0"  ## 先修改为 0
                          for x, y in [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]: ## 遍历上下左右
                              if 0 <= x < nr and 0 <= y < nc and grid[x][y] == "1": ## 碰到新的 1
                                  uf.union(r * nc + c, x * nc + y) ## 调用并查集函数
              
              return uf.count

后言

  • 并查集这个学得我好累,这就是缺乏基础吧,路漫漫啊 

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

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

相关文章

11.以太网交换机工作原理

目录 一、以太网协议二、以太网交换机原理三、交换机常见问题思考四、同网段数据通信全过程五、跨网段数据通信全过程六、关键知识七、调试命令 前言&#xff1a;在网络中传输数据时需要遵循一些标准&#xff0c;以太网协议定义了数据帧在以太网上的传输标准&#xff0c;了解以…

详细讲解:文物预防性保护解决方案的目标

一、文物预防性保护方案的系统目标 可移动文物预防性保护监测与调控系统,是博物馆开展科学、有效的预防性保护策略的关键工程&#xff0c;整套系统包括监测系统平台建设、调控设备部署、数据传输设备部署和环境数据监测设备安装工程。项目完成时将达到以下目标: 1)构建覆盖全…

如何在群晖NAS中开启FTP服务并实现公网环境访问内网服务

文章目录 1. 群晖安装Cpolar2. 创建FTP公网地址3. 开启群晖FTP服务4. 群晖FTP远程连接5. 固定FTP公网地址6. 固定FTP地址连接 本文主要介绍如何在群晖NAS中开启FTP服务并结合cpolar内网穿透工具&#xff0c;实现使用固定公网地址远程访问群晖FTP服务实现文件上传下载。 Cpolar内…

Flutter 数据持久化存储之Hive库

Flutter 数据持久化存储之Hive库 前言正文一、配置项目二、UI① 增加UI② 显示和删除UI 三、使用Hive① 初始化Hive② TypeAdapter自定义对象③ 注册TypeAdapter③ CURD 四、源码 前言 在Flutter中&#xff0c;有多种方式可以进行数据持久化存储。以下是一些常见的方式&#xf…

linux下查看某个命令在哪里个安装包程序下,以ifconfig命令举例子

yum list | grep net-tools &#xff08;查看yum安装列表中有没有安装指定的软件工具&#xff09;

Leetcoder Day29| 贪心算法part03

1005.K次取反后最大化的数组和 给定一个整数数组 A&#xff0c;我们只能用以下方法修改该数组&#xff1a;我们选择某个索引 i 并将 A[i] 替换为 -A[i]&#xff0c;然后总共重复这个过程 K 次。&#xff08;我们可以多次选择同一个索引 i。&#xff09; 以这种方式修改数组后&a…

Fast admin改变对话框的文字,并且绑定参数,确认和取消都可以做修改

需求&#xff1a;点击确认和拒绝都要做出对应的操作 列表添加一个buttos按钮用来单击触发对话框 {field: operate, title: __(Operate), table: table, events: Table.api.events.operate, buttons: [{name: click,title: __(点击执行事件),classname: btn btn-xs btn-info bt…

逆变器专题(6)-正负序分离(二阶广义积分器DSOGI)

相应仿真原件请移步资源下载 DSOGI作为一种常用的正负序分离方法&#xff0c;其可以在电压三相不平衡的状态下实现较为精准的锁相环。 原理 构建基于二阶广义积分器的自适应滤波器来实现90相角偏移和谐波的滤除。 其中&#xff0c;&#xff0c;表示原信号进行滞后90&#xff…

成功解决IndexError: Target 20 is out of bounds.

【PyTorch】成功解决IndexError: Target 20 is out of bounds. &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您…

Redisson限流算法

引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.12.3</version> </dependency>建议版本使用3.15.5以上 使用 这边写了一个demo示例&#xff0c;定…

kswapd0挖矿病毒攻击记录

文章目录 一、起因与病毒分析1、起因2、阿里云告警2.1 恶意脚本代码执行12.2 恶意脚本代码执行22.3恶意脚本代码执行32.4 恶意脚本代码执行4 3、病毒简单分析3.1 病毒的初始化3.2 病毒本体执行 4、总结 二、ubuntu自救指南1、病毒清理2、如何防御 一、起因与病毒分析 1、起因 …

跳跃游戏Ⅱ

问题 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - …

【深蓝学院】移动机器人运动规划--第7章 集群机器人运动规划--笔记

文章目录 0. Contents1. Multi-Agent Path Finding (MAPF)1.1 HCA*1.2 Single-Agent A*1.3 ID1.4 M*1.5 Conflict-Based Search(CBS)1.6 ECBS1.6.1 heuristics1.6.2 Focal Search 2. Velocity Obstacle (VO&#xff0c;速度障碍物)2.1 VO2.2. RVO2.3 ORCA 3. Flocking model&am…

EAS web 界面加载后,隐藏按钮

效果&#xff1a;隐藏下列按钮&#xff1a; 实现方法&#xff1a; 1、创建数据装载事件&#xff1a; 2、隐藏按钮&#xff1a; afterOnloadHideEntryTBBBBBB:function(e){console.log("----------失败222&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&a…

Redis主从、哨兵、Redis Cluster集群架构

Redis主从、哨兵、Redis Cluster集群架构 Redis主从架构 Redis主从架构搭建 主从搭建的问题 如果同步数据失败&#xff0c;查看log日志报错无法连接&#xff0c;检查是否端口未开放出现”Error reply to PING from master:...“日志&#xff0c;修改参数protected-mode no …

WebDAV之π-Disk派盘 + DAVx⁵

DAVx⁵是一款通过标准 CardDAV 和 CalDAV 协议同步通讯录、日历的 Android 应用,支持 iCloud 等云服务,只需要在 Android 端安装,即可实现在 iPhone 与 Android 间双向同步通讯录、日历、提醒事项等数据。 资源自动检测,支持自签名证书,通过客户端证书进行身份验证;可以…

如何使用Windows系统电脑无公网ip远程桌面Ubuntu系统

文章目录 前言1. ubuntu安装VNC2. 设置vnc开机启动3. windows 安装VNC viewer连接工具4. 内网穿透4.1 安装cpolar【支持使用一键脚本命令安装】4.2 创建隧道映射4.3 测试公网远程访问 5. 配置固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址5.3 测试…

SpringBoot整合rabbitmq-直连交换机队列(二)

说明&#xff1a;本文章主要是Direct定向/直连类型交换机的使用&#xff0c;它的大致流程是将一个队列绑定到一个直连交换机上&#xff0c;并赋予一个路由键 routingkey&#xff0c;当一个消息携带着路由值为routingkey&#xff0c;这个消息通过生产者发送给交换机时&#xff0…