DFS小结

DFS

        通过一些leetcode上面的题目, 总结出以下类型的题目;

  • 树先序遍历
  • DFS + 回溯
  • DFS + 记忆化
  • DFS + 减枝
  • DFS 求最短路
  • DFS 求联通块儿

先序遍历

        过于简单, 看看数据结构都能懂的。

题目


DFS + 回溯

        比较典型的问题是 迷宫, 八皇后 等问题, 也比较简单。

        当此题如果是判断某种情况存不存在, 则判断到存在的时候立马停止掉后续的所有DFS。

题目


DFS + 记忆化

        DFS过程当中同一个 节点的 状态可以多次进入, 而多次进入的需要求得结果均可使用第一次求得的结果, 这样能节省大量的时间。

模板

T dfs(...)
{
    if 子节点已经记载:
        求得当前顶点所对应的值
    else
        dfs(子节点)
        再求得当前顶点所对应的值

    //此处记载当前顶点对应的值。
}

题目

给定一个整数矩阵,找出最长递增路径的长度。
对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。

输入: nums = 
[
  [9,9,4],
  [6,6,8],
  [2,1,1]
] 
输出: 4 
解释: 最长递增路径为 [1, 2, 6, 9]。
分析

        当DFS过程当中, 记录下当前DFS过程当中每个顶点的最长上升长度, 当其余DFS过程再次进入这些顶点的时候, 能够直接使用而不用在递归了。


DFS + 减枝

        根据先前DFS路径当中求得的某些结果, 判断当前DFS是否继续进行下去。


DFS求最短路径

        列出如下三种情况求一个顶点到剩余所有顶点的最短距离, 求一个顶点最多只能经过K条边到剩余顶点的最短距离, 求一个顶点最多只能经过K条边到指定顶点的最短距离, 并作出 减枝条件的 对比。

题目1

编号从1-n的一个有向图, 求编号为1的顶点到其他顶点之间的最短距离。

分析

        当DFS过程当中发生一个顶点二次进入的时候, 减枝方法为: 只需判断 先前DFS得出的 1 到 当前顶点距离, 和 当前DFS得出的 1 到 当前顶点的距离即可, 前者大, 则继续DFS, 后者大, 则终止当前DFS。
1

题目2

顶点编号从1-n的有向图, 求出顶点1, 经过k条边所能到达的顶点的最短距离。

分析

        当DFS过程当中发生一个顶点的二次进入的时候, 不能再使用题目一当中的减枝条件了, 因为即使 1 到 当前顶点的距离比先前DFS计算的大, 但是可能 此 DFS 到当前顶点的经过的边数少, 能到达先前DFS过程中未能达到的顶点, 因此减枝条件为: 如果到达此顶点时经过的边数少于先前DFS到达此顶点时的边数, 则继续DFS, 反之 则 需要比较两次的DFS的距离, 此次距离小才能继续DFS, 否则减枝。

2

题目3

有 n 个城市通过 m 个航班连接。每个航班都从城市 u 开始,以价格 w 抵达 v。

现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到从 src 到 dst 最多经过 k 站中转的最便宜的价格。 如果没有这样的路线,则输出 -1。

示例 1:
输入: 
n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 1
输出: 200

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/
cheapest-flights-within-k-stops
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析

        当有K约束时候, 需要限定DFS的路径(深度) 不能超过K的同时, 减枝方法应该修改为: 如果当前路径长度已经大于先前 DFS 累计的长度, 则终止此条DFS路径(减枝非必须, 为了不超时)。
3

原文地址:https://www.cnblogs.com/Geek-Z/p/11396553.html