从二维数组中找字符串是否存在,而且同一个元素不能重复使用。这是字符串匹配类型题目,要记住方法。将二维数组简化成字符串,也就是字符串匹配了(依次遍历每个元素,将其当做开头,开始匹配)。
1、可以想到的是使用回溯法。
2、不能重复使用,想到用一个数组来标记每个元素的使用情况。
3、其实就是一个字符一个字符地匹配,当前字符相同,则向四周匹配。
4、从二维数组哪个字符开始匹配呢?遍历二维数组,依次将字符当做第一个字符跟字符串开始匹配。
————————————————
package bytetens;
/**
* @author :Administrator.
* @date :2020/8/10 0010
* @time:16:42
*/
import java.util.Scanner;
/**
* 给定一个二维网格和一个单词,找出该单词是否存在于网格中。
* 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
* 示例:
*
* board =
* [
* ['A','B','C','E'],
* ['S','F','C','S'],
* ['A','D','E','E']
* ]
*
* 给定 word = "ABCCED", 返回 true
* 给定 word = "SEE", 返回 true
* 给定 word = "ABCB", 返回 false
*/
public class 二维数组中查找单词 {
public static boolean exist(char[][] board, String word) {
if (board==null||board.length==0) {
return false;
}
int m = board.length;
int n = board[0].length;
boolean flag[] = new boolean[m*n];//标记二维数组的字符是否被使用
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (helper(board,i,j,flag,0,word)) {
return true;
}
}
}
return false;
}
/**
*
* @param board 二维字符数组
* @param i 字符数组行
* @param j 字符数组列
* @param flag 标记二维数组的字符是否被使用
* @param index 查找单词的第一个字母下标
* @param word 查找的单词
* @return
*/
private static boolean helper(char[][] board, int i, int j, boolean[] flag, int index, String word) {
if (index==word.length()) {//当index在word的最后一个下标说明全部找到了
return true;
}
//下标越界或者该位置的的字母已经用过或者该位置的字母和查找的单词不一样,return false
if(i<0||i>=board.length||j<0||j>=board[0].length||flag[i*board[0].length+j]||word.charAt(index)!=board[i][j]) {
return false;
}
//如果字母匹配的话,将该位置的单词标记为已使用
flag[i*board[0].length+j]=true;
//以该位置为中心上下左右依次递归查找每一个单词的字母
if (helper(board,i-1,j,flag,index+1,word)||helper(board,i+1,j,flag,index+1,word)
||helper(board,i,j+1,flag,index+1,word)||helper(board,i,j-1,flag,index+1,word)) {
return true;
}
//如果后面的不匹配,就得把当前的标志清除返回。
flag[i*board[0].length+j]=false;
return false;
}
}