BFS和DFS问题
广度优先遍历是利用队列实现的搜索算法,一层一层的进行递归,典型例题是之字形遍历树和树的层序遍历以及前中后序遍历
BFS的关键是队列,而DFS的关键是递归(也就是隐式的栈),回溯可以理解成是DFS的一种应用,只要是不撞南墙不回头都是DFS。
应用上:
1 | BFS 常用于找单一的最短路线,它的特点是 "搜到就是最优解" |
DFS的三种情况:
先上模板,当然不一定和模板一模一样,大致思路如此,比如标记着一步可能是隐式(比如指数型就两种情况,直接手动枚举情况了)的或者不需要,但是像结束条件是一定会有的。
1 | void dfs(int step) |
第一种:指数型枚举
从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案
分析: 从1~n依次考虑 选 和 不选 两种情况。 一共 n 个数,每个数有 2 种情况。总共方案数为 2的n次方。所以被称为指数型枚举。
1 | const int N = 1e1 + 6; 定义一个常量N |
排列型枚举,下面用全排列举例
把 1∼n 这 n 个整数排成一行后随机打乱顺序,输出所有可能的次序。
分析:依次枚举 1~n数 放到哪个位置,排列问题需要考虑顺序,需要book数组来判重。
1 | const int N = 10; |
组合型枚举
从 1∼n 这 n 个整数中随机选出 m 个,按字典序输出所有可能的选择方案。
组合问题和排列问题不同,不需要考虑顺序,即 1234 和 4321 都是一种组合.
因为要按字典序输出,所以需要从上一次枚举的数开始来依次枚举,控制局部枚举的数,使得新枚举的数比之前的大。
组合问题不需要考虑顺序,需要x来记录上一次的枚举的数。这样也就可以保证同一种组合只有一种顺序被打印。
因为是从上一次枚举的数开始枚举所以不会保存选用重复数字, 所以不需要定义去重数组book。
1 | int n,m; |
BFS扯扯淡
BFS可以解决最短(路径)问题,原因是BFS是层序遍历,第一个满足条件的目标节点一定是最短最近的那一个节点。
BFS可以解决最短路径、层序遍历(队列),走迷宫等其实也是类似于最短路径。
走迷宫注释
1 | package bfs; |
BFS模板(其他的容器以及变量需自己定义)
1 | void BFS () |
TOP K问题
两种思路:快排或者堆排
后者主要用在求最大最小的一个或多个(连续的)值,快排适用于求第K个最大最小以及获取多个最大最小的元素,快排求多个元素的话(比如获取最大的K个元素):在获取第k大的基础上,把index保存一下,不直接return了,而是完成整个快排,然后最后遍历原array从array.length-K到arr.length-1
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !