回溯法是做了剪枝改進的窮舉法,適合由多個步驟組成,並且每個步驟都有多個選項組成的問題。回溯法的解空間樹到達葉結點時,如果在葉子結點的狀態滿足題目的約束條件,那麼就找到了乙個可行的解決方案。
回溯二字在於,如果在解空間樹上的某個結點不滿足約束條件,那麼就退回到上一結點,再嘗試其它選項;如果全部試過都不行,再向上回溯。
面試題12:矩陣中的路徑
請設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格仔。例如在下面的3×4的矩陣中包含一條字串「bfce」的路徑(路徑中的字母用下劃線標出)。但矩陣中不包含字串「abfb」的路徑,因為字串的第乙個字元b佔據了矩陣中的第一行第二個格仔之後,路徑不能再次進入這個格仔。路徑可以被看成乙個棧,當第n個字元周圍都找不到第n+1個字元時,向上回溯一步。由於題目要求路徑不能進入重複的矩陣格仔,所以要定義乙個布林矩陣來標識路徑是否已經進入了每個格仔。
#include
using
namespace std;
// 引數:
// matrix: 字元矩陣首位址
// rows: 矩陣的行數
// cols: 矩陣的列數
// row: 當前行
// col: 當前列
// str: 要檢驗的字串行陣列
// pathlength: 當下這個點匹配的路徑長度
// visited: 訪問情況矩陣
// 返回值:
// 繼續向後匹配,true表示成功匹配,false表示匹配失敗
bool
haspathcore
(const
char
* matrix,
int rows,
int cols,
int row,
int col,
const
char
* str,
int& pathlength,
bool
* visited)
}return haspath;
//返回從這個位置能否完成匹配
}// 引數:
// matrix: 字元矩陣首位址
// rows: 矩陣的行數
// cols: 矩陣的列數
// str: 要檢驗的字串行陣列
// 返回值:
// true表示找到,false表示找不到
bool
haspath
(const
char
* matrix,
int rows,
int cols,
const
char
* str)}}
delete
visited;
//釋放輔助矩陣的空間
return
false
;//執行至此,說明匹配失敗,返回false
}//abtg
//cfcs
//jdeh
intmain()
面試題13:機械人的運動範圍地上有乙個m行n列的方格。乙個機械人從座標(0, 0)的格仔開始移動,它每一次可以向左、右、上、下移動一格,但不能進入行座標和列座標的數字之和大於k的格仔。例如,當k為18時,機械人能夠進入方格(35, 37),因為3+5+3+7=18。但它不能進入方格(35, 38),因為3+5+3+8=19。請問該機械人能夠到達多少個格仔?也是類似的問題,除了限制條件不同之外,這個問題是要求能夠到達多少格仔,所以四個方向的情況要加起來,而不是像上一題那樣用短路或。
#include
using
namespace std;
/*宣告部分*/
intmovingcountcore
(int threshold,
int rows,
int cols,
int row,
int col,
bool
* visited)
;bool
check
(int threshold,
int rows,
int cols,
int row,
int col,
bool
* visited)
;int
getdigitsum
(int number)
;// 引數:
// threshold: 閾值,即題目中的k值
// rows: 矩陣的行數
// cols: 矩陣的列數
// 返回值:
// 題目要求的結果,即機械人可達的格仔數目
intmovingcount
(int threshold,
int rows,
int cols)
// 引數:
// threshold: 閾值,即題目中的k值
// rows: 矩陣的行數
// cols: 矩陣的列數
// row: 當前行
// col: 當前列
// visited: 訪問情況矩陣
// 返回值:
// 從該點開始(有訪問情況矩陣限制不重複),新發現的可達點數目
intmovingcountcore
(int threshold,
int rows,
int cols,
int row,
int col,
bool
* visited)
//如果不能進入,自然返回0
return count;
//返回計數
}// 引數:
// threshold: 閾值,即題目中的k值
// rows: 矩陣的行數
// cols: 矩陣的列數
// row: 當前行
// col: 當前列
// visited: 訪問情況矩陣
// 返回值:
// true表示能進入該方格,false表示不能
bool
check
(int threshold,
int rows,
int cols,
int row,
int col,
bool
* visited)
//輸入正整數number,輸出其各個數字之和
intgetdigitsum
(int number)
return sum;
}int
main()
回溯法 機械人的運動範圍
此題出自牛客網的劍指offer專題 地上有乙個m行和n列的方格。乙個機械人從座標0,0的格仔開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數字之和大於k的格仔。例如,當k為18時,機械人能夠進入方格 35,37 因為3 5 3 7 18。但是,它不能進入方格 35...
回溯法 機械人的運動範圍
地上有乙個m行和n列的方格。乙個機械人從座標0,0的格仔開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數字之和大於k的格仔。例如,當k為18時,機械人能夠進入方格 35,37 因為3 5 3 7 18。但是,它不能進入方格 35,38 因為3 5 3 8 19。請...
回溯法應用之機械人的運動範圍
類似,這個方格也可以看出乙個m n的矩陣。同樣在這個矩陣中,除邊界上的格仔之外其他格仔都有四個相鄰的格仔。機械人從座標 0,0 開始移動。當它準備進入座標為 i,j 的格仔時,通過檢查座標的數字和來判斷機械人是否能夠進入。如果機械人能夠進入座標為 i,j 的格仔,我們接著再判斷它能否進入四個相鄰的格...