- 原题链接:79. 单词搜索
题目
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例 1:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
示例 2:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “SEE”
输出:true
1- 思路
回溯思路
- 根据题意,本题需要对每个方格上的字母进行搜索,搜索过程是检查其四个方向上的字母是否满足 word 的下一位,若满足继续搜索,若不满足则返回 false
- 因此根据该思路 ,回溯的 参数应该包括:①二维字符串数组、③word字符串、③纵 横坐标 row 、④纵坐标 col、⑤word的下标 index
回溯三部曲
- 1. 确定回溯的参数及返回值
public boolean backTracing(char[][] board,String word,int i,int j ,int index)
- 2. 判断终止条件
- 不满足结果的条件
-
- i 和 j 越界
-
- 当前 word 的 index 和 board[i][j] 不同
-
- 当前 位置的元素已经遍历过(通过 boolean[][] used 数组判断)
-
- 满足条件
- 当前 index 的值 和 word 的长度相同,证明遍历到了一个正确的 path。
// 结果
if(index==word.length()){
return true;
}
// 判断越界
if( i<0 || i>=board.length || j<0 || j>=board[0].length || word.charAt(index)!=board[i][j]||used
[i][j]){
return false;
}
- 3.回溯逻辑
- 回溯逻辑为,定义一个方向数组,之后 依次 按照上下左右的顺序进行回溯,如果回溯结果为 true 则返回 true。 否则返回false。
used[i][j] = true;
// 定义方向数组
int[][] dir = {{0,1},{1,0},{-1,0},{0,-1}};
for(int[] d:dir){
int nextX = i + d[0];
int nextY = j + d[1];
if(backTracing(board,word,nextX,nextY,index+1)){
return true;
}
}
used[i][j] = false;
return false;
2- 题解
⭐单词搜索—— 代码实现思路
class Solution {
boolean[][] used;
public boolean exist(char[][] board, String word) {
int row = board.length;
int col = board[0].length;
used = new boolean[row][col];
for(int i = 0 ; i < row;i++){
for(int j = 0 ; j < col;j++){
if(backTracing(board,word,i,j,0)){
return true;
}
}
}
return false;
}
public boolean backTracing(char[][] board,String word,int i,int j ,int index){
// 结果
if(index==word.length()){
return true;
}
// 判断越界
if( i<0 || i>=board.length || j<0 || j>=board[0].length || word.charAt(index)!=board[i][j]||used
[i][j]){
return false;
}
used[i][j] = true;
// 定义方向数组
int[][] dir = {{0,1},{1,0},{-1,0},{0,-1}};
for(int[] d:dir){
int nextX = i + d[0];
int nextY = j + d[1];
if(backTracing(board,word,nextX,nextY,index+1)){
return true;
}
}
used[i][j] = false;
return false;
}
}
3- ACM模式
public class hot59_exist {
public static boolean[][] used;
public static boolean exit(char[][] board,String word){
int n = board.length;
int m = board[0].length;
used = new boolean[n][m];
for(int i = 0 ; i < n;i++){
for(int j = 0 ; j < m;j++){
if(backTracing(board,word,i,j,0)){
return true;
}
}
}
return false;
}
public static boolean backTracing(char[][] board,String word,int i ,int j,int index){
// 结果
if(index==word.length()){
return true;
}
// 终止
if(i<0 || i>=board.length || j<0 || j>=board.length|| word.charAt(index)!=board[i][j] || used[i][j]){
return false;
}
// 回溯
used[i][j] = true;
int[][] dir = {{0,1},{1,0},{-1,0},{0,-1}};
for(int[] d:dir){
int nextX = i + d[0];
int nextY = j + d[1];
if(backTracing(board,word,nextX,nextY,index+1)){
return true;
}
}
used[i][j] = false;
return false;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("输入 行数 row");
int row = sc.nextInt();
System.out.println("输入 列数 col");
int col = sc.nextInt();
sc.nextLine(); // 消耗掉行尾的换行符
System.out.println("按行输入字符");
char[][] board = new char[row][col];
for (int i = 0; i < row; i++) {
String line = sc.nextLine();
for (int j = 0; j < col; j++) {
board[i][j] = line.charAt(j);
}
}
System.out.println("输入要找的字符");
String input = sc.nextLine();
System.out.println("搜索结果为"+exit(board,input));
}
}