搜尋回溯問題 滑動視窗

2021-10-03 04:39:15 字數 4370 閱讀 6203

參考鏈結,有八皇后問題

如迷宮問題:進入迷宮後,先隨意選擇乙個前進方向,一步步向前試探前進,如果碰到死胡同,說明前進方向已無路可走,這時,首先看其它方向是否還有路可走,如果有路可走,則沿該方向再向前試探;如果已無路可走,則返回一步,再看其它方向是否還有路可走;如果有路可走,則沿該方向再向前試探。按此原則不斷搜尋回溯再搜尋,直到找到新的出路或從原路返回入口處無解為止

搜尋偽**/公式

基本上所有的搜尋與回溯都是這個公式的變種

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 ...