回溯演算法(劍指offer)

2021-10-05 11:08:29 字數 2760 閱讀 4537

運用回溯法解題的關鍵要素有以下三點:

(1) 針對給定的問題,定義問題的解空間;

(2) 確定易於搜尋的解空間結構;

(3) 以深度優先方式搜尋解空間,並且在搜尋過程中用剪枝函式避免無效搜尋。

回溯法的基本思想:能進則進,不進則退,再換一條路走。(即按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇。)

題目描述

請設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意乙個格仔開始,每一步可以在矩陣中向左,向右,向上,向下移動乙個格仔。如果一條路徑經過了矩陣中的某乙個格仔,則該路徑不能再進入該格仔。 例如

矩陣中包含一條字串"bcced"的路徑,但是矩陣中不包含"abcb"路徑,因為字串的第乙個字元b佔據了矩陣中的第一行第二個格仔之後,路徑不能再次進入該格仔。

思路:注意到題目中的要求行走的路徑不能重複進入某格仔,因此需要建立乙個用來存放該點狀態(即是否已被訪問過,預設為false,已訪問則為true)的矩陣,且矩陣大小與原矩陣相對應。

路徑的每一次移動規則:只能向上,向下,向左,向右移動一格。

我們可以將路徑的行走過程看成是入棧的過程,當矩陣已定位了字串的前n個字元後,由第n個字元所對應的矩陣的位置分別向上,向下,向左,向右進行試探查詢對應第n+1個字元的位置,如果都沒有,路徑需要回退到第n-1個字元,將原始的第n個字元的標記flag進行調整,並且重新定位第n個字元。

注意給定函式中傳入的矩陣並不是以二維的形式傳入,而是將矩陣轉換為了一維陣列,並給定了行和列資訊,以此來確定輸入的矩陣格式。 因此**中的表示矩陣中的某乙個元素序號使用index = row*cols + col;

public

class

solution

}return

false;}

/** * 回溯法遞迴實現判斷

* @param matrix 字元矩陣

* @param rows 矩陣行數

* @param cols 矩陣列數

* @param row 當前行索引

* @param col 當前列索引

* @param str 目標字串行

* @param k 目標字串行中當前字元索引

* @param flag 字元矩陣是否被訪問過標記

* @return

*/public

static

boolean

haspathchar

(char

matrix,

int rows,

int cols,

int row,

int col,

char

str,

int k,

boolean

flag)

//終止迴圈的條件

if(k == str.length -1)

flag[index]

=true

; k++

;//在當前字元的上下左右進行搜尋匹配,遞迴實現if(

haspathchar

(matrix,rows,cols,row-

1,col,str,k,flag)

||haspathchar

(matrix,rows,cols,row+

1,col,str,k,flag)

||haspathchar

(matrix,rows,cols,row,col-

1,str,k,flag)

||haspathchar

(matrix,rows,cols,row,col+

1,str,k,flag)

)// 在當前字元的上、下、左、右的元素沒有搜尋到下乙個目標字元,將訪問標記重置為false,並且返回false;

flag[index]

=false

;return

false;}

}

題目描述

地上有乙個m行和n列的方格。乙個機械人從座標0,0的格仔開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數字之和大於k的格仔。 例如,當k為18時,機械人能夠進入方格(35,37),因為3+5+3+7 = 18。但是,它不能進入方格(35,38),因為3+5+3+8 = 19。請問該機械人能夠達到多少個格仔?

思路:本題思路與上一題大致相同:

都需要定義乙個字元矩陣用來標記該點是否被訪問過

迭代函式中都需要在開始處進行越界判定

進入迭代函式表示判斷已經進行一次了。

總之利用遞迴實現,每次只能走上下左右四個點,進行判斷點的位置是否越界,點數之和是否大於k,是否已經走過了。

public

class

solution

public

inthascore

(int row,

int col,

int rows,

int cols,

int threshold,

boolean

flag)

public

intnumsum

(int i)

return sum;

}}

劍指offer 回溯法

面試題12 矩陣中的路徑 上下左右遞迴,在看邊界條件 include includeusing namespace std 遞迴 bool haspathcore char m,int row,int col,int i,int j,const char str,int pathlen,bool v...

劍指offer 回溯法

題目描述 請設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意乙個格仔開始,每一步可以在矩陣中向左,向右,向上,向下移動乙個格仔。如果一條路徑經過了矩陣中的某乙個格仔,則該路徑不能再進入該格仔。例如 矩陣中包含一條字串 bcced 的路徑,但是矩陣中不包含...

劍指offer 回溯法總結

面試題12 13是接連的兩道回溯法的題。先上定義 回溯法的基本行為是搜尋,搜尋過程使用剪枝函式來為了避免無效的搜尋。剪枝函式包括兩類 1.使用約束函式,剪去不滿足約束條件的路徑 2.使用限界函式,剪去不能得到最優解的路徑。回溯法說白了就是遞迴,遞迴法演算法簡潔且執行效率高,但是與之相應的就是遞迴法一...