且说 深度优先搜索算法

       在我做LintCode上面算法题目的时候,发现深度优先搜索算法是一个实用性非常强的算法,它帮助我解决了很多题目。下面我就来谈一下我对这个算法的理解和应用。

        我觉得百度百科上面对于这个算法的解释还比较详细:

   定义:

    深度优先搜索算法(Depth-First-Search),是搜索算法的一种。是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,
搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节
点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。

方法步骤

假设初始状态是图中所有顶点都未被访问,则深度优先搜索方法的步骤是:
1)选取图中某一顶点Vi为出发点,访问并标记该顶点;
2)以Vi为当前顶点,依次搜索Vi的每个邻接点Vj,若Vj未被访问过,则访问和标记邻接点Vj,若Vj已被访问过,则搜索Vi的下一个邻接点;
3)以Vj为当前顶点,重复步骤2),直到图中和Vi有路径相通的顶点都被访问为止;
4)若图中尚有顶点未被访问过(非连通的情况下),则可任取图中的一个未被访问的顶点作为出发点,重复上述过程,直至图中所有顶点都被访问。

举例说明:

首先,我们来想象一只老鼠,在一座不见天日的迷宫内,老鼠在入口处进去,要从出口出来。那老鼠会怎么走?当然是这样的:老鼠如果遇到直路,就一直往前走,
如果遇到分叉路口,就任意选择其中的一个继续往下走,如果遇到死胡同,就退回到最近的一个分叉路口,选择另一条道路再走下去,如果遇到了出口,
老鼠的旅途就算结束了。深度优先搜索法的基本原则就是这样:按照某种条件往前试探搜索,如果前进中遭到失败(正如老鼠遇到死胡同),则退回头另选通路继续
搜索,直到找到条件的目标为止。

好了,引用了这么多内容,只是因为我觉得这些东西也正好是我的理解,总结的也比较好,但是写一篇博客,总要有自己的干货,下面,我就结合我自己用到的来谈下自己的理解:

青蛙跳 LintCode青蛙过河问题

    我解题的具体程序和思路就不说了,有兴趣的同学可以点击上面链接查看原博客。下面我只从深度优先搜索的角度分析我的程序。

private boolean canCross(int[] stones, int currentLocation, int lastStep) {                       //注释0
		if (currentLocation == stones.length - 1) return true;                           //注释1
		int next = 0;
		if ((next = findNextLocation(stones, currentLocation, lastStep + 1)) != -1       //注释2
				&& canCross(stones, next, lastStep + 1))                        //注释3
			return true;                                                            //注释4
		if ((next = findNextLocation(stones, currentLocation, lastStep)) != -1
				&& canCross(stones, next, lastStep))
			return true;
		if ((next = findNextLocation(stones, currentLocation, lastStep - 1)) != -1
				&& canCross(stones, next, lastStep - 1))
			return true;
		return false;                                                                    //注释5
	}

A。首先,深度优先搜索算法的一大特色就是使用递归,注释0就是这个递归方法的主题,这个方法有三个参数,分别是保存有所有石头位置的stones数组,当前的位置currentLocation,从上一步跨到这一步我的步距是多少,这三个缺一不可,因为我们需要由当前位置出发,结合上一步的步距来确定下一步的三种跨度方案(如果青蛙最后一个跳 k 个单位,那么它下一次只能跳 k – 1 ,k 或者 k + 1 个单位)。

B。注释1的代码说明青蛙已经跳到了最后一块石头上面,说明这个递归过程已经成功了,结束了。

C。由代码可知,每当青蛙跳到一块石头上面,青蛙就有三种选择,然后青蛙会逐个地对这三种选择进行尝试,如果第一种选择不行,就尝试第二种选择,第二种不行就尝试第三种,如果三种子方法全部不行,我就通知上一个调用我的方法,告诉他我这儿三种选择都失败了,然后上一级的节点方法就会调用我的兄弟方法,然后兄弟方法就会测试它的三个子方法,。。。依次类推。。

点赞