運用回溯法解題的關鍵要素有以下三點:
(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.使用限界函式,剪去不能得到最優解的路徑。回溯法說白了就是遞迴,遞迴法演算法簡潔且執行效率高,但是與之相應的就是遞迴法一...