DFS即深度优先搜索,通俗的讲就是在一棵递归搜索树中,从根节点沿着树的分支一直走到树的最深处,然后通过回溯再往回走,从而完成对整棵树的搜索。这需要我们对递归有一定的了解,能够画出或在脑中想象出搜索的路线。
通过dfs我们可以实现三种常见的题型(一维):
指数型枚举
每个位置有着相同的选择可能(一般来说是选或者不选两种可能),通过dfs以及状态数组st,记录得到每个位置的选择
## 指数型枚举
n = int(input())
st = [-1] * n
def dfs(x, st): # x代表的是当前枚举到哪个位置,st表示当前位置状态
if x == n: # 当x==n时,证明已经枚举完所有的位置
for i in range(n):
if st[i] == 1:
print(i+1, end='')
print()
return
for i in range(2):
st[x] = i #更新当前位置状态
dfs(x + 1, st) # 继续往下走,下一个位置
st[x] = -1 # 回溯
dfs(0, st)
输入:3
输出:
3
2
23
1
13
12
123
排列型枚举
相当于全排列,每个位置的元素不固定,通过dfs依次枚举每个位置的元素,并且已经枚举过的元素不能再次枚举,因此,我们需要一个状态数组st记录当前元素是否被使用过。(指数型枚举的状态数组记录的是当前位置是否已经被填充)
## 排列型枚举
n = int(input())
st = [False]*n
res = [-1]*n
def dfs(x, st, res):
# x表示当前枚举到哪个位置,st记录的是该元素是否被使用过,res记录的是枚举结果
if x == n: # 当x==n时,证明已经枚举完所有的位置
print(*res)
return
for i in range(n):
if not st[i]:
st[i] = True # 更新当前元素使用情况
res[x] = i+1 # 记录当前枚举结果
dfs(x + 1, st,res) # 继续往下走
st[i] = False # 恢复当前位置的元素的使用情况
res[x] = -1 # 恢复当前位置,将其设置为未枚举状态
dfs(0, st, res)
输入: 3
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
组合型枚举
类似于指数型枚举,有n个位置,每个位置有m种可能, 通过dfs依次枚举每个位置的所以可能(m的n次方)
n, m = map(int,input().split())
res = [0]*n
def dfs(x): # x表示当前枚举到哪个位置
if x == n: # 当x==n时,证明已经枚举完所有的位置
print(*res)
return
for i in range(m):
res[x] = i + 1 # 更新当前位置元素
dfs(x + 1) # 继续往下走
res[x] = 0 # 恢复当前位置元素,将其设置为未赋值状态
dfs(0)
输入: 3 5
输出:
1 1 1
1 1 2
1 1 3
1 1 4
1 1 5
1 2 1
1 2 2
1 2 3
1 2 4
1 2 5
1 3 1
1 3 2
1 3 3
(........剩余部分)