解決乙個回溯問題,本質是乙個決策樹的遍歷
三要素:
1.路徑:已經做出的選擇
2.選擇列表:當前可以做的選擇
3.結束條件:到達決策樹底層,不用再做選擇
演算法框架
result =
def backtrack
(path, choicelist)
:if 滿足結束條件:
result.
push_back
(path)
return
for choice in choicelist:
做選擇backtrack
(path, choicelist)
撤銷選擇
注意for迴圈中的遞迴
在遞迴前做選擇
在遞迴後撤銷選擇
permutations
交換dfs
class
solution
for(
int i = left; i < right;
++i)
} vectorint>>
permute
(vector<
int>
& nums)
};
傻瓜式完全照搬模板
class
solution
for(
int i =
0; i < nums.
size()
;++i)
} vectorint>>
permute
(vector<
int>
& nums)
};
這種時間反而是0
其中result和visit都可以是全域性變數
通過傳引用的方式實現
path的邏輯結構是棧
n-queens
笨比版面向過程程式設計
class
solution
bool
inbound
(int i,
int j)
return
false;}
bool
legal
(vector
& path,
int i,
int j)
for(
int r = i -
1, c = j +1;
inbound
(r, c);)
return
true;}
void
backtrack
(vector>
& res, vector
& path, vector<
int>
& vis)
for(
int i =
0; i < length;
++i)
} vector>
solvenqueens
(int n)
};
終極簡化版
class
solution
void
dfs(
int u)
// 即將要確定第u 行
for(
int i=
0;i< len;i++
)// 第i列是否可以放入path}}
};
每次加一行,不用考慮同行的情況
注意右對角線上i+j不變,左對角線上i-j+n不變
這兩個vec初始要設定成長度2n
course schedule
class
solution
bool
canfinish
(int numcourses, vectorint>>
& prerequisites)
for(
int i =
0; i < numcourses;
++i)if(
!dfs
(adjacency, flag, i)
)return
false
;return
true;}
};
通過dfs判斷拓撲排序
要先宣告adjacency長度為numcourse,不然無法訪問adjacency
restore ip addresses
class
solution
ans.
push_back
(ip)
;return;}
else
return;}
if(segnum ==4)
return
;// 0 的特殊情況要單獨考慮
// 0一定單獨存在
if(s[start]
=='0'
)int addr =0;
for(
int i = start; i < s.
size()
;++i)
else}}
vector
restoreipaddresses
(string s)
};
演算法 回溯演算法套路模板
回溯演算法應用 經典的全排列和n皇后 怎麼窮舉全排列的呢?比方說給三個不重複數 1,2,3 你肯定不會無規律地亂窮舉,一般是這樣 先固定第一位為 1,然後第二位可以是 2,那麼第三位只能是 3 然後可以把第二位變成 3,第三位就只能是 2 了 然後就只能變化第一位,變成 2,然後再窮舉後兩位 其實這...
dfs與回溯演算法
1,區別不在於回溯,因為dfs也會回溯,而是dfs會將已經訪問過的點標記為不可再次連線,不會再撤銷,從而使得可搜尋路徑越來越少,而回溯會在訪問初標記,回溯時撤銷。使用鄰接鍊錶的dfs的時間複雜度為v e 2,如果在尋徑中保留stack,我們會發現dfs只會找到一條a到b的路徑,而回溯法可以找到所有的...
回溯演算法套路 去重總結
回溯演算法模板 public void func int nums,list l,int start 這裡i的開頭如果從0開始是涉及到排列問題,如果是子集問題則需要從start開始 for int i 0 i nums.length i l.add nums i func nums,l,i l.re...