题目及测试
package pid079;
import java.util.List;
/*单词搜索
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.
*/
public class main {
public static void main(String[] args) {
char[][] testTable = {{'a','b','c','e'},{'s','f','c','s'},{'a','d','e','e'}};
String testTable2="abcd";
test(testTable,testTable2);
}
private static void test(char[][] ito, String ito2) {
Solution solution = new Solution();
long begin = System.currentTimeMillis();
System.out.println("ito= ");
for (int i = 0; i < ito.length; i++) {
for (int j = 0; j < ito[0].length; j++) {
System.out.print(ito[i][j]+" ");
}
System.out.println();
}//开始时打印数组
System.out.println("ito2="+ito2);
boolean rtn=solution.exist(ito,ito2);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn="+rtn);
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功,15ms,很快)
使用回溯算法,对board中每个与word首字母相同的字符ij,开启begin函数
begin中
如果result已经为true,不再继续
如果char[i][j]与word首字母不同,不再继续
如果相同,
如果word长度为1,说明已经到最后一步,result=true
否则,char[i][j]='*',因为让接下来的操作不到这一位
然后newWord=word截去首位的字符串
然后根据i,j的位置,对上下左右进行begin
最后char[i][j]=now,恢复
package pid079;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.text.AttributeSet.CharacterAttribute;
public class Solution {
public boolean result=false;
public boolean exist(char[][] board, String word) {
if(word.length()==0){
return true;
}
if(board.length==0||board[0].length==0){
return false;
}
for(int i=0;i<board.length;i++){
for(int j=0;j<board[i].length;j++){
char now=board[i][j];
char first=word.charAt(0);
if(now!=first){
continue;
}
else{
begin(board,word,i,j);
}
}
}
return result;
}
public void begin(char[][] board,String word,int i,int j){
if(result==true){
return;
}
char now=board[i][j];
char first=word.charAt(0);
if(now!=first){
return;
}
if(word.length()==1){
result=true;
return;
}
String newWord=word.substring(1);
board[i][j]='*';
if(i>0){
begin(board,newWord,i-1,j);
}
if(i<board.length-1){
begin(board,newWord,i+1,j);
}
if(j>0){
begin(board,newWord,i,j-1);
}
if(j<board[0].length-1){
begin(board,newWord,i,j+1);
}
board[i][j]=now;
}
}
解法2(成功,9ms,极快)
建立一个isVisited数组,如果对应成功就设置为true,然后match下一个字符,match后,再设置为false
public boolean exist(char[][] board, String word) {
int rows=board.length;
if(rows==0){
return false;
}
int cols=board[0].length;
if(cols==0){
return false;
}
boolean[][] isVisited=new boolean[rows][cols];
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
if(match(board, word, 0, i, j, rows, cols,isVisited)){
return true;
}
}
}
return false;
}
public boolean match(char[][] board, String word,int index,int i,int j,int rows,int cols,boolean[][] isVisited){
if(index==word.length()){
return true;
}
if(i<0||i>=rows){
return false;
}
if(j<0||j>=cols){
return false;
}
if(isVisited[i][j]==true){
return false;
}
if(board[i][j]!=word.charAt(index)){
return false;
}
isVisited[i][j]=true;
if(match(board, word, index+1, i+1, j, rows, cols,isVisited)||match(board, word, index+1, i-1, j, rows, cols,isVisited)||
match(board, word, index+1, i, j+1, rows, cols,isVisited)||match(board, word, index+1, i, j-1, rows, cols,isVisited)){
isVisited[i][j]=false;
return true;
}
isVisited[i][j]=false;
return false;
}