LeetCode - 栈和深度优先搜索

栈和DFS

与 BFS 类似,深度优先搜索(DFS)也可用于查找从根结点道目标结点的路径。

1.结点的处理顺序是什么?

在下图中,从根结点 A 开始。首先选择结点 B 的路径,并进行回溯,直到到达结点 E,无法更进一步。然后回溯到 A 并选择第二条路径到结点 C。从 C 开始,我们尝试第一条路径到 E 但是 E 已被访问过。所以我们回到 C 并尝试从另一条路径到 F。最后找到 G。

在这里插入图片描述

总的来说,在我们到达最深的结点之后,我们只会回溯并尝试另一条路径。

因此我们在 DFS 中找到的第一条路径不一定就是最短的路径。例如,在上面的例子中,我们成功找出了路径 A->C->F->G 并停止了 DFS。但这不是从 A 到 G 的最短路径。

2.栈的入栈和退栈顺序是什么?
如上面图示,首先将根结点推入到栈中;然后我们尝试第一个邻居 B 并将结点 B 推入到栈中;等等等等。当我们到达最深的结点 E 时,我们需要回溯。当我们回溯时,我们将从栈中弹出最深的结点,这实际上是推入到栈中的最后一个结点。

结点的处理顺序是完全相反的顺序,就像它们被添加到栈中一样,它是后进先出(LIFO)。这就是我们在 DFS 中使用栈的原因。

DFS-模版-1

在大多数情况下,我们在能使用 BFS 时也可以使用 DFS。但是有一个重要的区别:遍历顺序

与 BFS 不同,更早访问的结点可能不是更靠近根结点的结点。因此,你在 DFS 中找到的第一条路径可能不是最短路径。
以下是 DFS 的递归模板(JAVA),帮助我们更好的理解:

/*
 * Return true if there is a path from cur to target.
 */
boolean DFS(Node cur, Node target, Set<Node> visited) {
  return true if cur is target;
  for (next : each neighbor of cur) {
    if (next is not in visited) {
      add next to visted;
      return true if DFS(next, target, visited) == true;
    }
  }
  return false;
}

当我们递归地实现 DFS 时,似乎不需要使用任何栈。但实际上,我们使用的是由系统提供的隐式栈,也称为调用栈(Call Stack)

放在最后

如果您喜欢我的文章,拜托点赞+收藏+关注,博主会根据大家喜好来推出相关系列文章~

更多精彩内容也可以访问我的博客Aelous-BLog

猜你喜欢

转载自blog.csdn.net/Aelous_dp/article/details/107700018