一直不是太理解回溯法,這幾天集中學習了一下,記錄如下。
回溯法有「通用的解題法」之稱。
1.定義:
2.基本思想:
3.一般步驟:
4.約束函式:
5.限界函式:
6.子集樹模板
遍歷子集樹,時間複雜度 o(2^n)
如果解的長度是不固定的,那麼解和元素順序無關,即可以從中選擇0個或多個。例如:子集,迷宮,...
如果解的長度是固定的,那麼解和元素順序有關,即每個元素有乙個對應的狀態。例如:子集,8皇后,...
解空間的個數指數級別的,為2^n,可以用子集樹來表示所有的解
適用於:冪集、子集和、0-1揹包、裝載、8皇后、迷宮、...
a.子集樹模板遞迴版
'''求集合的所有子集'''
n = 4
#a = ['a','b','c','d']
a = [1, 2, 3, 4]
x = # 乙個解(n元0-1陣列)
x = # 一組解
# 衝突檢測:無
def conflict(k):
global n, x, x, a
return false # 無衝突
# 乙個例子
# 衝突檢測:奇偶性相同,且和小於8的子集
def conflict2(k):
global n, x, x, a
if k==0:
return false
# 根據部分解,構造部分集
s = [y[0] for y in filter(lambda s:s[1]!=0, zip(a[:k+1],x[:k+1]))]
if len(s)==0:
return false
if 0 < sum(map(lambda y:y%2, s)) < len(s) or sum(s) >= 8: # 只比較 x[k] 與 x[k-1] 奇偶是否相間
return true
return false # 無衝突
# 子集樹遞迴模板
def subsets(k): # 到達第k個元素
global n, x, x
if k >= n: # 超出最尾的元素
#print(x)
else:
for i in [1, 0]: # 遍歷元素 a[k] 的兩種選擇狀態:1-選擇,0-不選
if not conflict2(k): # 剪枝
subsets(k+1)
x.pop() # 回溯
# 根據乙個解x,構造乙個子集
def get_a_subset(x):
global a
return [y[0] for y in filter(lambda s:s[1]!=0, zip(a,x))]
# 根據一組解x, 構造一組子集
def get_all_subset(x):
return [get_a_subset(x) for x in x]
# 測試
subsets(0)
# 檢視第3個解,及對應的子集
#print(x[2])
#print(get_a_subset(x[2]))
print(get_all_subset(x))
b.子集樹模板非遞迴版
7.排列樹模板
遍歷排列樹,時間複雜度o(n!)
解空間是由n個元素的排列形成,也就是說n個元素的每乙個排列都是解空間中的乙個元素,那麼,最後解空間的組織形式是排列樹
適用於:n個元素全排列、旅行商、...
a.排列樹模板遞迴版
'''求[1,2,3,4]的全排列'''
n = 4
x = [1,2,3,4] # 乙個解
x = # 一組解
# 衝突檢測:無
def conflict(k):
global n, x, x
return false # 無衝突
# 乙個例子
# 衝突檢測:元素奇偶相間的排列
def conflict2(k):
global n, x, x
if k==0: # 第乙個元素,肯定無衝突
return false
if x[k-1] % 2 == x[k] % 2: # 只比較 x[k] 與 x[k-1] 奇偶是否相同
return true
return false # 無衝突
# 排列樹遞迴模板
def backkrak(k): # 到達第k個位置
global n, x, x
if k >= n: # 超出最尾的位置
print(x)
else:
for i in range(k, n): # 遍歷後面第 k~n-1 的位置
x[k], x[i] = x[i], x[k]
if not conflict2(k): # 剪枝
backkrak(k+1)
x[i], x[k] = x[k], x[i] # 回溯
# 測試
backkrak(0)
b.排列樹模板非遞迴版
回溯python 回溯法 python
class solution def permute self,nums list int list list int if not nums return nums result self.backtrack nums,result,return result def backtrack self...
記錄回溯法模板
給你乙個字串 s,請你將 s 分割成一些子串,使每個子串都是 回文串 返回 s 所有可能的分割方案。回文串 是正著讀和反著讀都一樣的字串。示例 1 輸入 s aab 輸出 a a b aa b 示例 2 輸入 s a 輸出 a 1 s.length 16 s 僅由小寫英文本母組成 回溯法 看到題目要...
關於回溯法 python
最近遇到這麼乙個題目,給定乙個數字集合a,和乙個目標值t,找到集合a中所有和為t的數字組合,乙個數字,可以多次出現。集合和t都為正整數 例子 輸入 2,3,6,7 t 7 輸出 7 2,2,3 usr bin env python candidate 2 5,1 list result defsea...