题目描述
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
示例
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
思路
- 采用深度优先搜索(DFS)方法求解
- 遍历二维字符网格,把每一个位置分别当做起点进行递归求解
- 如果当前递归位置超过二维数组边界,或当前位置二维数组中值和字符数组中值不相等,那么表示失败,返回
false
;反之,继续 - 如果当前索引是二维数组中最后一个字符,那表示寻找成功,返回
true
;反之,继续 - 把当前二维数组字符置为空,防止当前位置被重复访问;分别向当前二维数组位置的上下左右递归继续寻找字符数组的下移个位置,得到其递归结果;其次,恢复当前二维数组字符,然后返回递归结果
- 最后,如果二维数组遍历完,都没有返回结果,那表示不存在,返回
false
public class Solution {
public boolean exist(char[][] board, String word) {
char[] words = word.toCharArray();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (dfs(board, words, i, j, 0)) {
return true;
}
}
}
return false;
}
/**
* @param board 二维字符网格
* @param words 单词字符数组
* @param i 二维字符网格横坐标
* @param j 二维字符网格纵坐标
* @param index 单词字符遍历索引
* @return 结果
*/
private boolean dfs(char[][] board, char[] words, int i, int j, int index) {
//判断当前索引处值是否满足要求
if (i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != words[index]) {
return false;
}
if (index == words.length - 1) {
//是最后一个, 那么就表示找到了
return true;
}
//把当前位置设置为空, 这样做是防止被重复访问
board[i][j] = '\0';
//分别上下左右四个方向继续递归
boolean result = dfs(board, words, i + 1, j, index + 1) || dfs(board, words, i - 1, j, index + 1)
|| dfs(board, words, i, j + 1, index + 1) || dfs(board, words, i, j - 1, index + 1);
//恢复当前值
board[i][j] = words[index];
return result;
}
}
时间复杂度:O((3^K)MN)
空间复杂度:O(K)