【力扣hot100】刷题笔记Day15

前言

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

深搜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.mfbz.cn/a/417453.html

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

相关文章

17.题目:编号3766 无尽的石头

题目&#xff1a; ###本题主要考察模拟 #include<bits/stdc.h> using namespace std; int sum(int x){int result0;while(x){resultx%10;x/10;}return result; } int main(){int t;cin>>t;while(t--){int n;cin>>n;int buf1;int ans0;for(int i1;i<100…

[python] 利用已有字典创建新字典——dict.fromkeys()

有的时候&#xff0c;我们需要使用已有字典的key去创建新的字典&#xff0c;但是key对应的value不一样&#xff0c;比如说&#xff1a; old_dict {a:1, b:2, c:3} new_dict {a:1/3, b:1/3, c:1/3} old_dict和new_dict的key一样&#xff0c;但是value不一样。除了枚举创造的…

高级语言期末2011级B卷(计算机学院)

1.编写函数&#xff0c;实现按照如下公式计算的功能&#xff0c;其中n为自然数 #include <stdio.h>int fac(int n) {if(n0)return 1;elsereturn n*fac(n-1); }float fun(int n) {float flag;float sum0;for(int i0; i<n; i) {flagi/((i1)*fac(i2));sumflag;}return su…

初始Tomcat(Tomcat的基础介绍)

目录 一、Tomcat的基本介绍 1、Tomcat是什么&#xff1f; 2、Tomcat的配置文件详解 3、Tomcat的构成组件 4、Tomcat的顶层架构 5、Tomcat的核心功能 6、Tomcat的请求过程 一、Tomcat的基本介绍 1、Tomcat是什么&#xff1f; Tomcat 服务器是一个免费的开放源代码的Web …

Nacos配置

目录 启动nacos 项目步骤 Nacos服务分级存储模型​编辑 服务跨域集群调用问题 NacosRule负载均衡 服务实例的权重设置 环境隔离-namespace Nacos环境隔离 Nacos和Eureak对比 临时实例和非临时实例 Ncaos与Eureka的共同点 Nacos与Eureka的区别 Nacos配置管理 统一配…

java009 - Java面向对象基础

1、类和对象 1.1 什么是对象 万物皆对象&#xff0c;客观存在的事物皆为对象。 1.2 什么是面向对象 1.3 什么是类 类是对现实生活中一类具有共同属性和行为的事物抽象。 特点&#xff1a; 类是对象的数据类型类是具有相同属性和行为的一组对象的集合 1.4 什么是对象的属…

求两个向量之间的夹角

求两个向量之间的夹角 介绍Unity的API求向量夹角Vector3.AngleVector3.SignedAngle 自定义获取方法0-360度的夹角 总结 介绍 求两个向量之间的夹角方法有很多&#xff0c;比如说Unity中的Vector3.Angle&#xff0c;Vector3.SignedAngle等方法&#xff0c;具体在什么情况下使用…

Juniper Netscreen208 防火墙 忘记密码恢复出厂配置(同时会清空配置)

0. 遇到的Juniper防火墙忘记密码的情况和2种方法 之前有Juniper SRX3400 防火墙&#xff0c;忘记密码&#xff0c;参考Juniper srx 防火墙密码恢复进行了恢复&#xff0c;但该方法对Juniper Netscreen208 防火墙不起作用&#xff0c;按空格键中断启动后&#xff0c;不会出现lo…

React入门之React_使用es5和es6语法渲染和添加class

React入门 //react的核心库 <script src"https://cdn.jsdelivr.net/npm/react17/umd/react.development.js"></script> //react操作dom的核心库&#xff0c;类似于jquery <script src"https://cdn.jsdelivr.net/npm/react-dom17/umd/react-dom.…

SuMa++代码阅读记录

文章目录 流程梳理1. 打开点云文件2. 播放点云数据3. SUMA部分的流程图说明3.1 SUMA核心流程分析&#xff0c;其中也包含部分SUMA3.2 preprocess部分3.3 updatePose部分3.4 updateMap部分 4. SUMA中有关语义模型rangenet的部分4.1 下面是解析模型引擎4.2 下面这块是从配置文件中…

力扣细节题:判断是否为平衡二叉树

经典题&#xff0c;需要记忆&#xff0c;且注意fabs和fmax函数的使用 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/int deep(struct TreeNode*root){if(rootNULL){return 0;}r…

SpringBoot多数据源配置(MySql、Oracle)

一、依赖 <!-- dynamic-datasource 多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId></dependency><!--oracle驱动--><dependency><groupI…

【探索AI】探索未来-计算机专业必看的几部电影

计算机专业必看的几部电影 计算机专业必看的几部电影&#xff0c;就像一场精彩的编程盛宴&#xff01;《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力&#xff1b;《社交网络》揭示了互联网巨头的创业之路&#xff0c;《源代码》带你穿越时间解救世界&#xff0c;…

价格腰斩:腾讯云和阿里云服务器优惠价格对比

2024年阿里云服务器和腾讯云服务器价格战已经打响&#xff0c;阿里云服务器优惠61元一年起&#xff0c;腾讯云服务器62元一年&#xff0c;2核2G3M、2核4G、4核8G、8核16G、16核32G、16核64G等配置价格对比&#xff0c;阿腾云atengyun.com整理阿里云和腾讯云服务器详细配置价格表…

Huggingface初上手即ERNIE-gram句子相似性实战

大模型如火如荼的今天&#xff0c;不学点语言模型&#xff08;LM&#xff09;相关的技术实在是说不过去了。只不过由于过往项目用到LM较少&#xff0c;所以学习也主要停留在直面——动眼不动手的水平。Huggingface&#xff08;HF&#xff09;也是现在搞LM离不开的工具了。 出于…

javaee教程郑阿奇,一线互联网架构师筑基必备技能之Java篇

一、什么情况下会发生栈内存溢出&#xff1f; 1、栈是线程私有的&#xff0c;栈的生命周期和线程一样&#xff0c;每个方法在执行的时候就会创建一个栈帧&#xff0c;它包含局部变量表、操作数栈、动态链接、方法出口等信息&#xff0c;局部变量表又包括基本数据类型和对象的引…

【InternLM 实战营笔记】XTuner 大模型单卡低成本微调实战

XTuner概述 一个大语言模型微调工具箱。由 MMRazor 和 MMDeploy 联合开发。 支持的开源LLM (2023.11.01) InternLM Llama&#xff0c;Llama2 ChatGLM2&#xff0c;ChatGLM3 Qwen Baichuan&#xff0c;Baichuan2 Zephyr 特色 傻瓜化&#xff1a; 以 配置文件 的形式封装了大…

Springboot中ApplicationContextInitializer的使用及源码分析

文章目录 一、认识ApplicationContextInitializer1、ApplicationContextInitializer的作用2、认识ApplicationContextInitializer接口3、ApplicationContextInitializer的常用用法&#xff08;1&#xff09;注册BeanFactoryPostProcessor&#xff08;2&#xff09;注册Applicat…

【程序员的金三银四求职宝典】《春风拂面,代码在手:程序员的金三银四求职指南》

《春风拂面&#xff0c;代码在手&#xff1a;程序员的金三银四求职指南》 随着春风的轻拂&#xff0c;大地复苏&#xff0c;万物更新。在这个生机勃勃的季节&#xff0c;不仅自然界在迎接新生&#xff0c;对于广大的程序员朋友们而言&#xff0c;这也是一个全新的开始——金三…

【刷题】 Leetcode 1022.从根到叶的二进制数之和

刷题 1022.从根到叶的二进制数之和题目描述&#xff1a;思路一&#xff08;dfs深搜万能版&#xff09;思路二 &#xff08;栈迭代巧解版&#xff09;总结 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇文章见&#xff…
最新文章