回溯法應用
阿新 • • 發佈:2018-12-22
問題:設計一個函式,來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑就不能再次進入該格。
解題思路:這是一個回溯法的應用。首先,在矩陣中任選一個格子作為路徑的起點,如果矩陣中某個格子的字元為ch,並且這個格子將對應於路徑上的第i個字元。如果路徑上的第i個字元不是ch,那麼這個格子不可能處在路徑上的第i個位置。如果路徑上的第i個字元正好是ch,那麼到相鄰的格子尋找路徑上的第i+1個字元。除了矩陣邊界上的格子外,其他格子都有4個相鄰的格子。重複這個過程,知道路徑上的所有字元都在矩陣中找到相應的位置。路徑可以被看成一個棧,當在矩陣中定位了路徑中前n個字元的位置後,在與第n個字元對應的格子周圍都沒有找到第n+1個字元,這時候就只好回退到路徑的第n-1個字元,重新定位第n個字元。由於不能重複進入一個格子,所以還需要定義和字元矩陣大小一樣的bool值來表示該格子是否可以進入。
bool bPathker(const char *matrix, int row, int col, int i, int j, const char *str, int &pathlen, bool *isvaliable) { if(str[pathlen] == '\0') return true; bool hasPath = false; if(i >= 0 && i < row && j >= 0 && j < col && matrix[i * row + j] == str[pathlen] && !isvaliable[i * row + j]) { ++pathlen; isvaliable[i * row + j] = true; hasPath = bPathker(matrix, row, col, i, j-1, str, pathlen, isvaliable) || bPathker(matrix, row, col, i-1, j, str, pathlen, isvaliable) || bPathker(matrix, row, col, i, j+1, str, pathlen, isvaliable) || bPathker(matrix, row, col, i+1, j, str, pathlen, isvaliable); if(!hasPath) { --pathlen; isvaliable[i * row + j] =false; } } return hasPath; } bool bPath(char *matrix, int row, int col, char *str) { if(matrix == nullptr || row < 1 || col < 1 || str == nullptr) return false; bool *isvaliable = new bool[row * col]; memset(isvaliable, 0, row*col); int pathlen = 0; for(int i = 0; i < row; i++) { for(int j = 0; j < col; j++) { if(bPathker(matrix, row, col, i, j, str, pathlen, isvaliable)) { return true; } } } delete[] isvaliable; return false; }