「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。
给定一个
char[][] matrix,也就是char类型的二维数组,再给定一个字符串word,可以从任何一个某个位置出发,可以走上下左右,能不能找到word?设定1:可以走重复路的情况下,返回能不能找到 比如,word = "zoooz",是可以找到的,z -> o -> o -> o -> z,因为允许走一条路径中已经走过的字符
设定2:不可以走重复路的情况下,返回能不能找到 比如,word = "zoooz",是不可以找到的,因为允许走一条路径中已经走过的字符不能重复走
char[][] m = {
{ 'a', 'b', 'z' },
{ 'c', 'd', 'o' },
{ 'f', 'e', 'o' }
}
一、分析
f(i,j,k):从m[i][j]这个字符出发,能不能找到str[k...]这个后缀串,当k==str.length时,说明匹配的是空串,也返回true(能找到)
二、实现
// 可以走重复路
// 从m[i][j]这个字符出发,能不能找到str[k...]这个后缀串
public static boolean canLoop(char[][] m, int i, int j, char[] str, int k) {
if (k == str.length) {
return true;
}
if (i == -1 || i == m.length || j == -1 || j == m[0].length || m[i][j] != str[k]) {
return false;
}
// 不越界!m[i][j] == str[k] 对的上的!
// str[k+1....]
boolean ans = false;
if (canLoop(m, i + 1, j, str, k + 1) || canLoop(m, i - 1, j, str, k + 1) || canLoop(m, i, j + 1, str, k + 1)
|| canLoop(m, i, j - 1, str, k + 1)) {
ans = true;
}
return ans;
}
// 不能走重复路
// 从m[i][j]这个字符出发,能不能找到str[k...]这个后缀串
public static boolean noLoop(char[][] m, int i, int j, char[] str, int k) {
if (k == str.length) {
return true;
}
if (i == -1 || i == m.length || j == -1 || j == m[0].length || m[i][j] != str[k]) {
return false;
}
// 不越界!也不是回头路!m[i][j] == str[k] 也对的上!
m[i][j] = 0;
boolean ans = false;
if (noLoop(m, i + 1, j, str, k + 1) || noLoop(m, i - 1, j, str, k + 1) || noLoop(m, i, j + 1, str, k + 1)
|| noLoop(m, i, j - 1, str, k + 1)) {
ans = true;
}
m[i][j] = str[k];
return ans;
}
三、总结
走重复路优化:
- 记忆化缓存(杀缓存)
- 严格位置的动态规划
不能走重复路:
- 标记
- 恢复