题目
字母迷宫游戏初始界面记作 m x n 二维字符串数组 grid,请判断玩家是否能在 grid 中找到目标单词 target。
注意:寻找单词时 必须 按照字母顺序,通过水平或垂直方向相邻的单元格内的字母构成,同时,同一个单元格内的字母 不允许被重复使用 。
示例 1:
输入:grid = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], target = "ABCCED"
输出:true
示例 2:
输入:grid = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], target = "SEE"
输出:true
示例 3:
输入:grid = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], target = "ABCB"
输出:false
提示:
m == grid.length
n = grid[i].length
1 <= m, n <= 6
1 <= target.length <= 15
grid 和 target 仅由大小写英文字母组成
代码
class Solution {
int n;
int m;
int len;
boolean[][] visited;
public boolean wordPuzzle(char[][] grid, String target) {
this.n = grid.length;
this.m = grid[0].length;
this.len = target.length();
visited = new boolean[n][m];
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(dsf(grid, i, j, target, 0)){
return true;
}
}
}
return false;
}
boolean dsf(char[][] grid, int i, int j, String target, int k){
// 判断是否越界,已经访问过或者不匹配
if(i < 0 || i >= n || j < 0 || j >= m || grid[i][j] != target.charAt(k)){
return false;
}
if(k == len - 1){
return true;
}
//visited[i][j] = true;
grid[i][j] = '\n';
// 四个方向都搜索一下
boolean res = dsf(grid, i, j + 1, target, k + 1) ||
dsf(grid, i + 1, j, target, k + 1) ||
dsf(grid, i, j - 1, target, k + 1) ||
dsf(grid, i - 1, j, target, k + 1);
grid[i][j] = target.charAt(k);
return res;
// 时间复杂度:mn * 3^len
}
}
时间复杂度:O(3^K * MN) : 最差情况下,需要遍历矩阵中长度为 KK 字符串的所有方案,时间复杂度为 O(3^K);矩阵中共有 MN 个起点,时间复杂度为 O(MN)
空间复杂度:O(k)