在y总的算法进阶课里,主要讲了BFS和DFS
虽然y总将二者又细分成了很多类别(bfs下面有flood fill、最短路模型、最小步数模型……)但个人感觉bfs没有必要分这么多种

以下是一些总结:
1、bfs vs dfs:前者可以用来求最短(保证第一次搜到的是最短的)但是需要用很多的空间,而且代码相对复杂一些;而后者有可能存在“爆栈”的风险(函数递归调用的形式本质上就是栈的操作)
因此 dfs更常用 而一些有最短性质的题目则可以考虑bfs

&个人理解:因为搜索算法必须要存储状态 dfs的话要么放在函数的参数里、要么放在全局变量里 而bfs必须放在queue里面(?)感觉很不灵活 e.g.小猫爬山那道题我是怎么也想不出来怎么用bfs来做(可能我tcl)
反正就是觉得bfs一般用在有明显“图”结构的题目中(或者是数字华容道这种方便表示状态的题目) 而dfs就灵活很多!

2、bfs的st数组用法 vs dijkstra算法中的st数组:
st数组的目的是用来优化的 减少冗余情况 bfs中每个点不会第二次入队 因此入队的时候就可以判断&更新st(用st数组阻止冗余情况入队)
而dijkstra并不能保证 他的st数组表示的是该点是否已确定最小值 因此出队更新&判断

3、dfs之剪枝!
这是一个很神奇的方法……
根据y总的讲法,有4种剪枝:
(一)优化搜索顺序(优先枚举子节点少的情况!)
(二)排除等效冗余
(三)可行性剪枝(如果预知不可行那就return)
(四)最优性剪枝(如果预知非最优那就return && 如果最好的方案已经得到了 那就可以不用继续dfs下去了)

看起来好像很复杂 实际上我感觉就是
1、在设计方案的时候就要尽量少走弯路(搜索顺序烂/搜索方案差会增加很多不必要的时间,等效冗余也是)
2、尽可能快速地知道这条路能不能走下去
3、在失败之后得到尽可能多的信息(比如“木棒”那一题 如果小木棍放在首位的时候不行 那这个分支整个就不行)

4、双向搜索!
如果我们知道初状态和末状态分别是啥 那么就可以双向搜 可以减去很多状态空间!(尤其适用于有步数限制的题目)

5、dfs之迭代加深
和4差不多 都是减少状态空间的方法 这个方法适用于答案比较浅但是有些烂分支比较深的情况(而且这个方法可以搜出最小值hh)

posted on 2024-03-29 22:53  fireineye  阅读(2)  评论(0编辑  收藏  举报