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

leetcode 所有可能的路径(图的遍历)

 leetcode 链接:

 所有可能的路径

1 图的基本概念

1.1 有向图和无向图

左边是有向图,右边是无向图。对于无向图来说,图中的边没有方向,两个节点之间只可能存在一条边,比如 0 和 1 之间的边,因为是无向图,这条边可以表示从 0 到 1 的边,也可以表示从 1 到 0 的边。对于有向图来说,图中的边有方向, 0 和 1 之间可以存在两条边,一条表示从 0 到 1 的边,一条表示从 1 到 0 的边。

用邻接矩阵来表示上边两个图,如下所示。

// 有向图
[[1], // 有从 0 到 1 的边[0, 2], // 从 1 到 0 的边和从 1 到 2 的边[0]  // 从 2 到 0 的边
]// 无向图
[[1, 2], // 从 0 到 1 和从 0 到 2 的边[0, 2], // 从 1 到 0 和从 1 到 2 的边[0, 1]  // 从 2 到 0 和从 2 到 1 的边
]

1.2 有环图和无环图

讨论有环图还是无环图,一般说的是有向图。因为对于无向图来说,从 0 到 1 有边,那么从 1 到 0 就有边,本身就是一个环。

有环图说的是从一个节点开始遍历,在遍历过程中还能遍历到这个节点的图,除了开始节点和结束节点是相同的,其它节点不能重复出现,并且路径长度大于 2。

在图的遍历算法中,为了防止一个节点被重复遍历,往往需要一个 visited[n] 数组来标记一个节点是不是被遍历过。visited 数组下标是节点的值,元素值均被初始化为 0,当一个节点被遍历时,则将值改为 1。对于有向有环图来说,需要 visited 数组来标记,因为有环,一个节点可能被多次访问;对于有向无环图来说,一个节点不会被重复遍历,所以不需要 visited 数组来标记。

1.3 连通图和非连通图

下边两个图,上边的是非连通图,下边的是连通图。连通图,指的是从一个节点出发沿着边进行遍历,能把图中的节点都遍历到的图。 这个很像那种益智小游戏,看怎么样能一笔把图中的所有点连起来。

当对图做遍历时,如果图是连通的,那么从一个节点开始,遍历一次,就能将图中所有的节点遍历一遍,所以遍历一次就可以了。如果图不是连通的,那么遍历一次,无法将所有的点都遍历一遍,这个时候要从每个点都开始,每个节点都要开始一次,遍历一遍。

2 深度优先搜索和广度优先搜索

图是一种二维的数据结构,可以使用邻接表或者邻接矩阵来表示,更多的使用邻接表来表示,有行和列。

1.3 节中连通图的邻接矩阵表示如下:

深度优先,从遍历过程来看,优先在纵向遍历,纵深,深度。

广度优先,从遍历过程来看,优先在横向遍历,横向是广度。

纵向是深度,横向是广度。

上边这个图,从节点 0 开始遍历,第一步遍历到节点 1,下一步遍历的选择就是深度优先和广度优先的区别。下一步遍历 1 节点开始的链表,也就是跳到第二行开始遍历,遍历到节点 1 的邻接点 2,这就是深度优先遍历;下一步还是在 0 这一行,遍历节点 2,这就是广度优先遍历。

深度优先遍历和广度优先遍历不仅仅适用于图这种数据结构。二叉树的遍历包括前序遍历,中序遍历,后序遍历以及层序遍历。前 3 种遍历方式属于深度优先遍历,层序遍历属于广度优先遍历。二叉树也属于二维的数据结构。

二叉树遍历算法和应用

3 所有可能的路径

如下是 leetcode 中的题目说明。

题意中的图是有向无环图,有向并且没有环,所以在遍历的时候不需要使用 visited 数据来标记一个节点是不是被访问过,因为没有环,一个节点不会被重复访问。

这个题目适合使用深度优先遍历算法。深度优先遍历,是递归算法,递归算法需要注意两点:递归退出条件,一定要有退出条件,否则会一直递归下去;递归体,也就是递归算法的主要逻辑。递归算法的这两点与循环类似,循环算法也包括循环退出条件和循环主要逻辑。

找路径的题目,使用递归算法的题目,不管是图和是二叉树,最核心的就是如下代码注释中的三段式。

(1)将节点加入到路径

(2)递归

(3)将节点移出路径

为什么加入的节点要移出呢,因为这个节点加入之后,进行了递归运算。也就是说以这个节点为基础的路径都已经全部遍历。下一次要遍历的节点与这个节点是并列的节点,并不是路径的前后关系,它们属于这一行的邻接点。要进行下一步遍历,这个节点需要移出,因为后边遍历的节点跟这个节点不在一个路径,只不过都是当前这一行的得邻接点而已。

class Solution {
public:vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {const int n = graph.size();// 没有数据,直接返回if (n == 0) {return ret;}// 要找的路径是从 o 到 n - 1// 所以从 0 开始遍历// 在遍历之前要把这个点加入到路径中one_path.push_back(0);// 深度优先遍历DfsScan(graph, 0, n);return ret;}// 深度优先遍历时一种递归算法void DfsScan(vector<vector<int>>& graph, int index, const int n) {// 递归退出条件,当前这个点是 n - 1 的时候,说明找到了这样一个路径// 将这条路径加入到结果中if (index == n - 1) {ret.push_back(one_path);return;}// 递归体,深度优先搜索// 对于遍历的这个节点,找到这个节点锁代表的这一行,遍历这一行// 这种方式取出数据的一行,会发生拷贝,直接使用引用来获取数据可以避免数据拷贝//   vector<int> line = graph[index];//   int line_size = line.size();//   for (int i = 0; i < line_size; i++) {for (int & data : graph[index]) {// 三段式// 1、push_back 将节点加入到路径中// 2、递归运算// 3、将节点从路径中移走one_path.push_back(data);DfsScan(graph, data, n);one_path.pop_back();}}private:vector<vector<int>> ret;vector<int> one_path;
};

相关文章:

  • Ansible——unarchive模块
  • 异步复位和同步释放
  • myEclipse新手使用教程
  • 【SpringBoot】SpringBoot整合RabbitMQ消息中间件,实现延迟队列和死信队列
  • ssm物流管理系统-计算机毕业设计源码44323
  • 模式识别判断题
  • 2024教资认定报名流程,点赞收藏!
  • 【Python报错】已解决ModuleNotFoundError: No module named ‘xxx.yyy‘
  • 8. 正则表达式
  • Linux路由设置
  • HTTP/HTTPS Testing Magic Tool GO-VCR
  • Linux网络-自定义协议、序列化和反序列化、网络计算服务器的实现和Windows端客户端
  • 如何在快团团上找到优质的供货团长和挑选合适的产品进行推广?
  • Django与MySQL:配置数据库的详细步骤
  • windows环境安装多版本jdk与环境切换
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • GitUp, 你不可错过的秀外慧中的git工具
  • Java 内存分配及垃圾回收机制初探
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • mysql_config not found
  • React-Native - 收藏集 - 掘金
  • SpiderData 2019年2月13日 DApp数据排行榜
  • spring boot 整合mybatis 无法输出sql的问题
  • Vue小说阅读器(仿追书神器)
  • 聚类分析——Kmeans
  • 前端之Sass/Scss实战笔记
  • 提醒我喝水chrome插件开发指南
  • 推荐一个React的管理后台框架
  • 问题之ssh中Host key verification failed的解决
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 源码安装memcached和php memcache扩展
  • 大数据全解:定义、价值及挑战
  • ​520就是要宠粉,你的心头书我买单
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • # 利刃出鞘_Tomcat 核心原理解析(二)
  • $jQuery 重写Alert样式方法
  • (~_~)
  • (07)Hive——窗口函数详解
  • (11)(2.1.2) DShot ESCs(四)
  • (16)Reactor的测试——响应式Spring的道法术器
  • (8)STL算法之替换
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (四) Graphivz 颜色选择
  • (四)JPA - JQPL 实现增删改查
  • (五)MySQL的备份及恢复
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • .cfg\.dat\.mak(持续补充)
  • .CSS-hover 的解释
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .Net Core缓存组件(MemoryCache)源码解析
  • .NET Core跨平台微服务学习资源