Python递归实现回溯算法
回溯算法是一种解决问题的常用算法,常用于求解排列组合问题、迷宫问题、八皇后等问题。回溯算法通过枚举所有可能的解,逐步排除不满足条件的解,最后得到所有符合条件的解。
回溯算法通常通过递归实现,因为它要不断尝试不同的选择直到找到符合条件的解,或者排除所有不符合条件的解。在每一层递归中,需要依次尝试所有可能的选择,并判断是否满足条件。如果满足条件,则继续递归调用下一层,否则回溯到上一层,尝试其他的选择。
下面我们以字符串的全排列问题为例,演示如何使用递归实现回溯算法。
首先是代码实现:
def backtrack(s: str, path: str, used: set): """ 回溯函数实现 :param s: 原始字符串 :param path: 当前遍历的路径 :param used: 已使用的字符集合 """ if len(path) == len(s): # 如果遍历的路径长度等于原始字符串长度,说明找到了一个符合要求的全排列 print(path) return for i in range(len(s)): if i in used: continue # 尝试选择一个未使用的字符 used.add(i) path += s[i] # 进入下一层递归,继续尝试下一个字符 backtrack(s, path, used) # 回溯到上一层,尝试其他可能的字符 path = path[:-1] used.remove(i) def permutation(s: str): """ 字符串全排列函数 :param s: 原始字符串 """ used = set() backtrack(s, "", used)
代码中的 backtrack
函数是回溯函数,它接受三个参数:原始字符串 s
,当前遍历的路径 path
和已使用的字符集合 used
。这三个参数分别代表当前搜索的状态、选择的路径以及需要避免的决策。
permutation
函数是求解字符串全排列问题的函数,它调用 backtrack
函数完成搜索和回溯操作。
接下来是代码的解释:
首先在 backtrack
函数中,如果遍历路径的长度等于原始字符串的长度,说明已经找到一个符合要求的全排列,直接输出即可。
if len(path) == len(s): # 如果遍历的路径长度等于原始字符串长度,说明找到了一个符合要求的全排列 print(path) return
然后是对每个字符的处理,这里使用了一个字符集合 used
来避免重复选择。对于每个未使用的字符,将其添加到 used
中,将其添加到 path
中,并进入下一层递归操作。如果当前选择的字符不符合要求,则回溯到上一层调用,将其从 used
和 path
中删除,尝试其他的选择。
for i in range(len(s)): if i in used: continue # 尝试选择一个未使用的字符 used.add(i) path += s[i] # 进入下一层递归,继续尝试下一个字符 backtrack(s, path, used) # 回溯到上一层,尝试其他可能的字符 path = path[:-1] used.remove(i)
最后是字符串全排列函数 permutation
,它创建了一个空的字符集合 used
,并将其传递给 backtrack
函数。
def permutation(s: str): """ 字符串全排列函数 :param s: 原始字符串 """ used = set() backtrack(s, "", used)
最后,我们使用“pidancode.com”、“皮蛋编程”作为测试示例:
permutation("pidancode.com") print("==================") permutation("皮蛋编程")
输出结果如下:
pidancode.com pidancode.cmo pidancode.ocm pidancode.omc pidancode.mco pidancode.moc ... ================== 皮蛋编程 皮蛋编程 皮编蛋程 皮编程蛋 皮程蛋编 皮程编蛋 ...
相关文章