DFS入门(深度优先搜索)

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........剩余部分)

在这里插入图片描述

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chosen1&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值