深度遍历实例(阿里评测编程)
复习下深度遍历~
题目简述:给定二维列表,可以任意位置出发,可以上下左右四个方向移动,只朝着比当前位置元素小的方向移动,输出所有可能得最长路径以及移动的步数。
思考:
1、考虑到每步上下左右四个方向试探,满足情况时选择一个方向移动,不满足时回退到上一个位置,选择其他满足的方向移动,即深度遍历。
2、每移动一步后到达新位置,继续从新位置出发移动又是类似的操作,所以可以用递归实现。
3、题中有个小的技巧,为的是求最长的路径,所以本想着遍历二维列表每个元素为任意的起点,分别找到相应最长的最后进行比较。现在的做法是:之前遍历过的点已经存储了最长的路径,就没有必要再重复遍历。
步骤:
了解完题干后,递归函数只需要四个参数,当前坐标点x,y,移动步数step,记录路径path。
1、在当前位置,先循环四个方向进行尝试。
2、尝试过程中判断下一位置是否越界,是否满足条件,满足条件后递归step+1步。
3、当无路可走时,记录最长路径以及步数。
1 #coding:utf-8
2 a = [[19,20,18],[17,15,16],[15,14,30],[14,2,21]]
3 #b用来在深度优先遍历中标记是否遍历过,b_all:循环任意位置做起点时,标记该起点在之前是否已经遍历过
4 b = [[0,0,0],[0,0,0],[0,0,0],[0,0,0]]
5 b_all = [[0,0,0],[0,0,0],[0,0,0],[0,0,0]]
6 #a数组的大小m行n列
7 m,n = 4,3
8 #root是最终输出的最长路径
9 root = []
10 path = []
11 max_path = 0
12 #代表四个方向位置的移动
13 next = [(0,1),(1,0),(0,-1),(-1,0)]
14 def dfs(x, y , step, path):
15 global max_path, a, b, m, n, root, b_all, next
16 if path ==None:
17 path = []
18 path.append((x,y))
19 #按照右下左上的顺序枚举四个方向
20 for i in range(4):
21 tx = x + next[i][0]
22 ty = y + next[i][1]
23 #判断是否越界
24 if(tx < 0) or (ty<0) or ty> n-1 or tx>m-1:
25 continue
26 #判断是否满足条件以及是否走过
27 if a[tx][ty] <a[x][y] and b[tx][ty]==0:
28 # 标记这个点走过
29 b[tx][ty] = 1
30 # 标记已经遍历过这个点
31 b_all[tx][ty] = 1
32 # 开始尝试下一个点
33 dfs(tx,ty,step+1,path)
34 #尝试结束,取消这个点的标记
35 b[tx][ty] =0
36
37 #当所有方向尝试完,没有可以走的方向为止,记录下最长的路径以及步数
38 if step>max_path:
39 root=path[:]
40 max_path = step
41 return
42
43 for i in range(m):
44 for j in range(n):
45 #遍历每个未遍历过的元素为起点
46 if b_all[i][j]==0:
47 x,y = i,j
48 dfs(x,y,0,None)
49
50 print max_path,root
一般的dfs基本模型:
def dfs(step):
判断边界
尝试每一种可能
for i in range(n):
继续下一步dfs(step+1)
返回