參考鏈結,有八皇后問題
如迷宮問題:進入迷宮後,先隨意選擇乙個前進方向,一步步向前試探前進,如果碰到死胡同,說明前進方向已無路可走,這時,首先看其它方向是否還有路可走,如果有路可走,則沿該方向再向前試探;如果已無路可走,則返回一步,再看其它方向是否還有路可走;如果有路可走,則沿該方向再向前試探。按此原則不斷搜尋回溯再搜尋,直到找到新的出路或從原路返回入口處無解為止
搜尋偽**/公式
基本上所有的搜尋與回溯都是這個公式的變種
void
search
(int k)
//別人寫的
void
search
(int k)
}}
八皇后問題
八皇后注:八皇后沒有標記問題,是因為每個節點只能被訪問一次
題目給定乙個二維網格和乙個單詞,找出該單詞是否存在於網格中。
單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中「相鄰」單元格是那些水平相鄰或垂直相鄰的單元格。同乙個單元格內的字母不允許被重複使用。
題解題解
int
findnextitem
(int row,
int column,
int string_index)
//從row, column搜string_index開始的字元
if(board[row]
[column]
== word[string_index]
)//滿足條件才標記,否則返回0
//map[new_row][new_column] = 0;
} map[row]
[column]=0
;}return0;
}class
solution,,
,};int rows, cols;
public
:bool
haspath
(char
* matrix,
int rows,
int cols,
char
* str)}}
return
false;}
//judge(初始矩陣,索引行座標i,索引縱座標j,矩陣行數,矩陣列數,待判斷的字串,字串索引初始為0即先判斷字串的第一位)
bool
judge
(char
* matrix,
int i,
int j,
int rows,
int cols,vector<
bool
>
&flag,
char
*str,
int k)
//走到這,說明這一條路不通,還原,再試其他的路徑
flag[index]
=false
;return
false;}
};
二叉樹路徑總和題目
給定乙個二叉樹和乙個目標和,找到所有從根節點到葉子節點路徑總和等於給定目標和的路徑。
說明: 葉子節點是指沒有子節點的節點。
示例:給定如下二叉樹,以及目標和 sum = 22,
5
/ \4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[[5,4,11,2],
[5,8,4,5]
]思路:遞迴求解,當前層處理將當前值加入到temp的vector裡面,如果左子樹非空,左子樹遞迴,如果右子樹非空,右子樹遞迴,如果節點為葉子節點,判斷是否left_sum == node->val 從而加入結果中。
**注意本題用到回溯,**原因是如果不用回溯,則將不斷拷貝vector,時間消耗很大,如果採用引用方式,則不用拷貝,但是當前值判斷結束後要pop_back
void
calculateaddnode
(vector<
int>
&path,treenode *node,
int left_sum)
if(node -
> right !=
null)if
(node-
>left ==
null
&& node-
>right ==
null)}
path.
pop_back()
;}
求沒有重複數字的全排列
給定乙個 沒有重複 數字的序列,返回其所有可能的全排列。
題目
void
dfs(vector<
int>
&nums,
int index, vector<
int>
&cur)
for(
int i =
0; i < nums.
size()
; i++)}
}
括號組合
給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。
思路:遞迴引數是剩餘的左括號數和剩餘的右括號數,兩個都為0加入,右括號大於左括號剪枝。
void
dfs(
int left,
int right, string cur)
if(right < left)
return;if
(left >0)
dfs(left -
1, right, cur +
"(");if
(right >0)
dfs(left, right -
1, cur +
")")
;}
題目鏈結
class
solution
vector< vector<
int>> direction=,,
,};public
:int
numislands
(vector
char
>>
& grid)
}return num;
}void
dfs(
int row_i,
int col_j, vector
int>>
&map, vector
char
>>
&grid)
}void
bfs(
int row_i,
int col_j, vector
int>>
&map, vector
char
>>
&grid));
map[row_i]
[col_j]=1
;while
(!queue_bfs.
empty()
)); map[new_row]
[new_col]=1
;}}}}};
leetcode鏈結
int left =
0, right =0;
while
(right < s.
size()
)}/* 滑動視窗演算法框架 */
void
slidingwindow
(string s, string t)
}
這樣的好處是如果right遍歷到最後乙個元素時,while可以不斷優化.
基本思想
通過dijkstra計算圖g中的最短路徑時,需要指定起點s(即從頂點s開始計算)。
此外,引進兩個集合s和u。s的作用是記錄已求出最短路徑的頂點(以及相應的最短路徑長度),而u則是記錄還未求出最短路徑的頂點(以及該頂點到起點s的距離)。
初始時,s中只有起點s;u中是除s之外的頂點,並且u中頂點的路徑是」起點s到該頂點的路徑」。然後,從u中找出路徑最短的頂點,並將其加入到s中;接著**,更新u中的頂點和頂點對應的路徑(s不需要更新)**。 然後,再從u中找出路徑最短的頂點,並將其加入到s中;接著,更新u中的頂點和頂點對應的路徑。 … 重複該操作,直到遍歷完所有頂點。
暴力搜尋 回溯法
回溯法 backtracking 是深度優先搜尋 dfs 的一種,按照深度優先的順序便利解答樹。應用範圍很廣,只要能把待求解的問題分成不太多的步驟,每個步驟又只有不太多的選擇,都可以考慮應用回溯法。在學習回溯法之前,一定要保證遞迴程式能熟練準確地寫出。當把問題分成若干步驟並遞迴求解時,如果當前步驟沒...
poj 1935 搜尋 回溯
解題思路 先我們考慮從源點出發到所有自己想要經過的點然後在回到源點sum,顯然每條邊都必須經過源點 這個我們可以一次dfs求出 但題目的意思是可以不用回到源點,那麼我們可以再求源點到所有要經過的點的最遠距離ans,於是答案便是sum ans.這道題的思路確實是很巧妙,一開始我還是在想如何表示從某一點...
2021 3 1 79 單詞搜尋 回溯法)
題目 給定乙個二維網格和乙個單詞,找出該單詞是否存在於網格中。單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中 相鄰 單元格是那些水平相鄰或垂直相鄰的單元格。同乙個單元格內的字母不允許被重複使用。示例 board a b c e s f c s a d e e 給定 word abcced ...