You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class08;
/*
* 给定一个char[][] matrix也就是char类型的二维数组再给定一个字符串word
* 可以从任何一个某个位置出发可以走上下左右能不能找到word
* 比如:
* char[][] m = {
* { 'a', 'b', 'z' },
* { 'c', 'd', 'o' },
* { 'f', 'e', 'o' },
* };
* word = "zooe"
* 是可以找到的
*
* 设定1可以走重复路的情况下返回能不能找到
* 比如word = "zoooz"是可以找到的z -> o -> o -> o -> z因为允许走一条路径中已经走过的字符
*
* 设定2不可以走重复路的情况下返回能不能找到
* 比如word = "zoooz",是不可以找到的,因为允许走一条路径中已经走过的字符不能重复走
*
* 写出两种设定下的code
*
* */
public class Code03_FindWordInMatrix {
// 可以走重复的设定
public static boolean findWord1(char[][] m, String word) {
if (word == null || word.equals("")) {
return true;
}
if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
return false;
}
char[] w = word.toCharArray();
int N = m.length;
int M = m[0].length;
int len = w.length;
// dp[i][j][k]表示必须以m[i][j]这个字符结尾的情况下能不能找到w[0...k]这个前缀串
boolean[][][] dp = new boolean[N][M][len];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
dp[i][j][0] = m[i][j] == w[0];
}
}
for (int k = 1; k < len; k++) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
dp[i][j][k] = (m[i][j] == w[k] && checkPrevious(dp, i, j, k));
}
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (dp[i][j][len - 1]) {
return true;
}
}
}
return false;
}
// 可以走重复路
// 从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;
}
public static boolean checkPrevious(boolean[][][] dp, int i, int j, int k) {
boolean up = i > 0 ? (dp[i - 1][j][k - 1]) : false;
boolean down = i < dp.length - 1 ? (dp[i + 1][j][k - 1]) : false;
boolean left = j > 0 ? (dp[i][j - 1][k - 1]) : false;
boolean right = j < dp[0].length - 1 ? (dp[i][j + 1][k - 1]) : false;
return up || down || left || right;
}
// 不可以走重复路的设定
public static boolean findWord2(char[][] m, String word) {
if (word == null || word.equals("")) {
return true;
}
if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
return false;
}
char[] w = word.toCharArray();
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[0].length; j++) {
if (process(m, i, j, w, 0)) {
return true;
}
}
}
return false;
}
// 从m[i][j]这个字符出发能不能找到w[k...]这个后缀串
public static boolean process(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] == 0 || m[i][j] != str[k]) {
return false;
}
m[i][j] = 0;
boolean ans = false;
if (process(m, i + 1, j, str, k + 1) || process(m, i - 1, j, str, k + 1) || process(m, i, j + 1, str, k + 1)
|| process(m, i, j - 1, str, k + 1)) {
ans = true;
}
m[i][j] = str[k];
return ans;
}
public static void main(String[] args) {
char[][] m = { { 'a', 'b', 'z' }, { 'c', 'd', 'o' }, { 'f', 'e', 'o' }, };
String word1 = "zoooz";
String word2 = "zoo";
// 可以走重复路的设定
System.out.println(findWord1(m, word1));
System.out.println(findWord1(m, word2));
// 不可以走重复路的设定
System.out.println(findWord2(m, word1));
System.out.println(findWord2(m, word2));
}
}