class Solution {
public boolean exist(char[][] board, String word) {
//选择可以开始的一个格子,回溯法继续搜索上下左右四个位置
for(int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
if(backTracing(board, word, i, j, 0)) return true;
}
}
return false;
}
public boolean backTracing(char[][] board, String word, int i, int j, int k){
if(i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != word.charAt(k)){
return false;
}
if(k == word.length() - 1) return true;
board[i][j] = '\0';
boolean res = backTracing(board, word, i - 1, j, k + 1)||backTracing(board, word, i + 1, j, k + 1)
||backTracing(board, word, i, j - 1, k + 1)||backTracing(board, word, i, j + 1, k + 1);
board[i][j] = word.charAt(k);
return res;
}
}
class Solution:
def __init__(self):
self.n = 0
self.m = 0
# self.visitedList = []
def exist(self, board: list[list[str]], word: str) -> bool:
self.n = len(board)
self.m = len(board[0])
# self.visitedList = [[False for _ in range(self.m)] for __ in range(self.n)]
# 用两层for循环固定单词的第一个值
for i in range(self.n):
for j in range(self.m):
if self.dfs(board,i,j,word,0):
return True
return False
def dfs(self,board,i,j,word,k):
'''
深度优先遍历
Args:
board:
i,j:定位board的索引
word:
k: 固定word中的第k个元素
'''
# 终止条件
# 不越界,未走过,值相等
# if i < 0 or i >= self.n or j < 0 or j >= self.m or self.visitedList[i][j] or board[i][j] != word[k]:
# 这里由于在原list中进行标记
if i < 0 or i >= self.n or j < 0 or j >= self.m or board[i][j] != word[k]:
return False
if k == len(word)-1:
return True
# 对已经走过的路径进行标注
# self.visitedList[i][j] = True
# 也可以不使用一个专门的二维列表标记路径,而是直接在原列表中将这个元素改成一个不可能是答案的数来作为标记
board[i][j] = '~~~'
# 遍历每个阶段的可选解集合(规定方向是右,下,左,上)
res = self.dfs(board,i,j+1,word,k+1) or self.dfs(board,i+1,j,word,k+1) or self.dfs(board,i,j-1,word,k+1) or self.dfs(board,i-1,j,word,k+1)
# 回溯,需要去掉原来走过的路径的标记
# self.visitedList[i][j] = False
# 如果不用布尔list标记路径,在回溯时,就需要恢复原列表中的该元素,这里能等于word【k】是因为能够回溯说明之前这个位置的值是对的
board[i][j] = word[k]
return res
class Solution {
private int row;
private int col;
public boolean exist(char[][] board, String word) {
this.row = board.length;
this.col = board[0].length;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if(dfs(board, word, i, j, 0))
return true;
}
}
return false;
}
public boolean dfs (char[][] board, String word, int i, int j, int k) {
if(i < 0 || i >= row || j < 0 || j >= col || board[i][j] != word.charAt(k) )
return false;
if(k == word.length() - 1)
return true;
board[i][j] = '\0';
boolean res = dfs(board, word, i, j + 1, k + 1) ||
dfs(board, word, i + 1, j, k + 1) ||
dfs(board, word, i, j - 1, k + 1) ||
dfs(board, word, i - 1, j, k + 1);
board[i][j] = word.charAt(k);
return res;
}
}
class Solution {
int m;
int n;
int len;
public boolean exist(char[][] board, String word) {
this.m = board.length;
this.n = board[0].length;
this.len = word.length();
visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (dfs(board, i, j, word, 0)) {
return true;
}
}
}
return false;
}
boolean dfs(char[][] board, int i, int j, String word, int k) {
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word.charAt(k)) {
return false;
}
if (k == len - 1) {
return true;
}
board[i][j] = '\n';
boolean res = dfs(board, i, j + 1, word, k + 1) ||
dfs(board, i + 1, j, word, k + 1) ||
dfs(board, i, j - 1, word, k + 1) ||
dfs(board, i - 1, j, word, k + 1);
board[i][j] = word.charAt(k);
return res;
}
}
共以下 14 个回答
回溯算法,1word是字符串 2注意边界值有没有等号,有没有-1
回溯
时间复杂度:O(MN)
空间复杂度:O(K)
时间复杂度O(3 ^ k *mn),空间复杂度为O(1)
时间:O(mn * n ^ len),空间:O(mn)
dfs
时间复杂度:O(3^K * MN) : 最差情况下,需要遍历矩阵中长度为 K 字符串的所有方案,时间复杂度为 O(3^K);矩阵中共有 MN 个起点,时间复杂度为 O(MN)
空间复杂度O(mn)