题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如
a b c e
s f c s
a d e e
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
思路一:
采用DFS寻找路径,每次递归调用后,记得还原状态。
代码一:
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str) {
if(matrix == NULL || rows < 1 || cols < 1 || str == NULL) {
return false;
}
bool *visited = new bool[rows * cols];
memset(visited, false, rows * cols);
int pathLength = 0;
for(int row = 0; row < rows; ++row) {
for(int col = 0; col < cols; ++col) {
if(hasPathCore(matrix, rows, cols, row, col, str, pathLength, visited))
return true;
}
}
delete[] visited;
return false;
}
bool hasPathCore(char* matrix, int rows, int cols, int row, int col, char* str, int& pathLength, bool* visited) {
if(str[pathLength] == '\0')
return true;
bool hasPath = false;
if(row >= 0 && row < rows && col >= 0 && col < cols
&& matrix[row * cols + col] == str[pathLength]
&& !visited[row * cols + col]) {
++pathLength;
visited[row * cols + col] = true;
hasPath = hasPathCore(matrix, rows, cols, row - 1, col, str, pathLength, visited) ||
hasPathCore(matrix, rows, cols, row + 1, col, str, pathLength, visited) ||
hasPathCore(matrix, rows, cols, row, col - 1, str, pathLength, visited) ||
hasPathCore(matrix, rows, cols, row, col + 1, str, pathLength, visited);
if(!hasPath) { //回溯还原状态
--pathLength;
visited[row * cols + col] = false;
}
}
return hasPath;
}
};
思路二:
采用BFS,广度优先遍历,自定义结构体State,并用辅助队列,当找到一条符合条件的路径时立即返回true,若都没有符合条件的路径,最终返回false。
代码二:
typedef pair<int, int> Pos;
struct State {
Pos p;
int s;
vector<int> vis;
State(Pos pos, int step, vector<int> visit) : p(pos), s(step), vis(visit) {}
};
class Solution {
int dx[4] = {0, 0, 1, -1};
int dy[4] = {-1, 1, 0, 0};
public:
bool hasPath(char* matrix, int rows, int cols, char* str) {
if(matrix == NULL || rows < 1 || cols < 1 || str == NULL) {
return false;
}
queue<State> q;
int maxS = strlen(str) - 1;
vector<int> v(rows * cols, 0);
for(int i = 0; i < rows; ++i) {
for(int j = 0; j < cols; ++j) {
if(matrix[i * cols + j] == str[0]) {
v[i * cols + j] = 1;
q.push(State(Pos(i, j), 0, v));
v[i * cols + j] = 0;
}
}
}
while(!q.empty()) {
auto t = q.front();
q.pop();
auto p = t.p; //get position x, y
auto x = p.first;
auto y = p.second;
auto s = t.s; //get current step
auto vis = t.vis; //get check array
//operation
if(s == maxS) return true;
//next move
for(int d = 0; d < 4; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
int ns = s + 1;
if(nx >= 0 && nx < rows && ny >= 0 && ny < cols &&
matrix[nx * cols + ny] == str[ns] && !vis[nx * cols + ny]) {
vis[nx * cols + ny] = 1;
q.push(State(Pos(nx, ny), ns, vis));
}
}
}
return false;
}
};