使用图DFS(Depth-First-Search)解决排列组合问题

背景

      在近期的项目中,有一个的功能设计,此功能有一个将指标修饰词进行排列组合的步骤。
      一开始的觉得这里使用多重循环就可以解决,随着实践发现了一些暴力算法的局限性,有想起来之前做图计算最短路径的深度优先搜索DFS算法,在这个场景加以变化正好适用。

场景

需要对多种类型的修饰词进行组合
例:
类型A的值有: 1,2
类型B的值有: a,b,c
那么组合的结果就有:1,a; 1,b; 1,c; 2,a; 2,b; 2,c;1 ;2 ;a ;b ; c 共11种

暴力算法与其局限

      使用双循环就可以达到目的,这里就不做编码示例了。
      但是局限显而易见,当我不知道有多少种类型的数据要进行组合的话,多层for循环的编码就无法实现了。

DFS算法

      DFS算法其实是一种图算法,此算法简单地说就是使用递归方法模拟穷举搜索的过程。在图的起点我们可以选择不同的方向去查找下一个点,然后在新的点又可以选择不同的方向去找下一个点。深度优先(deep-first)体现在每次遍历都是优先朝同一方向前进,直到遇到边界的时候返回,再去探索其他方向。如下图所示:



      结合项目中的场景,需要对不同的项做排雷组合,我们可以先将数据转为二维数组,再给数组加上边界,数据就成为了一个有x,y两个方向的二维图,就可以使用DFS的方法去遍历数据并且进行排列组合了。还是以上面的数据再加一个类型C为例:

  • 类型A的值有: 1,2
  • 类型B的值有: a,b,c
  • 类型C的值有:1,2,3,4,5,6,7

      由于组合中还要考虑到一些类型不取的情况,比如类型A,C的值都取空,组合结果可以为a。
所以我们可以在每个类型后添加一个值-1表示不取值。

  • 类型A: 1,2,-1
  • 类型B: a,b,c,-1
  • 类型C:1,2,3,4,5,6,7,-1

这时比如遍历结果为-1,a,1 其实就是a,1这个结果。

      然后是数据结构选型,这里可以使用二维数据,类型的数目(x)就是第一维的长度,每个类型的最大长度+1(maxlen+1,因为要加-1这个边界值所以为maxlen+1)就是第二维度的长度。
现在可将数据放入二维数据data[x][maxlen+1],初始化后为data[3][8]:

  • 类型A: 1,2,-1,-1,-1,-1,-1,-1
  • 类型B: a,b,c,-1,-1,-1,-1,-1
  • 类型C:1,2,3,4,5,6,7,-1

      按照DFS算法的思路,从data[0][0]出发,结合实际的需求(做不同类型项的组合),在这个二维的图中应该优先向下走,再向右走,比如data[0][0]=1的下一步应当优先为data[1][0]=a。

  • 当无法继续向下走的时候(也就是完成了一个组合如 1,a,1)再向右走。

  • 当向右移动的时候到达新的点仍然是遵循先向下再向右的规则(比如到达data[2][1]位置时,无法向下走此时有了新组合1,a,2)。

  • 每次向下走的时候,需要把第二维的角标置为0,这是和标准图算法DFS不一样的地方。比如:data[1][0]位置࿰

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值