题目链接:https://leetcode.cn/problems/ju-zhen-zhong-de-lu-jing-lcof/
1. 题目介绍(12. 矩阵中的路径)
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
【测试用例】:
示例 1:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
示例2:
输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false
【条件约束】:
提示:
- m == board.length
-n = board[i].length
-1 <= m, n <= 6
-1 <= word.length <= 15
-board 和 word 仅由大小写英文字母组成
【相同题目】:
注意:本题与 【LeetCode】No.79. Word Search – Java Version 相同
2. 题解
2.1 回溯 – O(3k mn)
时间复杂度O(3k mn)
空间复杂度O(1),但要使用辅助数据来记录访问的话,就增长到了O(mn)
【注意点】:
- 错误条件:索引越界、当前数组值不匹配当前字符、当前值已被访问
- 成功条件:字符串已经成功被匹配
index == w.length()-1
其它具体细节可参见:面试题12. 矩阵中的路径( DFS + 剪枝 ,清晰图解)
class Solution {
static int m;
static int n;
static boolean[][] visited;
// 回溯法
public boolean exist(char[][] board, String word) {
// m: 行数;n: 列数
m = board.length;
n = board[0].length;
visited = new boolean[m][n];
// 1. 遍历board,在数组中找到第一个匹配字符,然后开始回溯
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
if (board[i][j] == word.charAt(0) &&
search(board,word,0,i,j)) return true;
}
}
return false;
}
public boolean search(char[][] b, String w, int index, int i, int j){
// 错误条件
if (i < 0 || i >= m || j < 0 || j >= n || b[i][j] != w.charAt(index) || visited[i][j] == true) return false;
// 回溯成功条件:即在数组中找到了字符串word
if (index == w.length()-1) return true;
// // 临时更改数组值,使其无法被重复使用,防止回头
// char tmp = b[i][j];
// b[i][j] = '0';
visited[i][j] = true;
// 回溯
if (search(b,w,index+1,i+1,j)||
search(b,w,index+1,i-1,j)||
search(b,w,index+1,i,j+1)||
search(b,w,index+1,i,j-1))
return true;
// 恢复数组,如果不允许直接操作数组,那么就需要一个boolean数组来辅助判断了
// b[i][j] = tmp;
visited[i][j] = false;
// 不满足条件,返回false
return false;
}
}
3. 参考资料
[1] 面试题12. 矩阵中的路径( DFS + 剪枝 ,清晰图解) – 图片来源
[2] 【LeetCode】No.79. Word Search – Java Version – 相同题目