79.单词搜索
解题思路:
package leadcode;
/**
* @author : icehill
* @description : 单词搜索
* <p>
* 给定一个 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
* 示例3:
* 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
* 输出:false
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/word-search
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
* 解题思路:
* 深度优先搜索(需要额外的isVisit空间,判断元素是否重复使用)
* 时间复杂度:一个非常宽松的上界为 O(MN⋅3^L)其中 M,N 为网格的长度与宽度,L 为字符串word 的长度。
* 空间复杂度:O(MN)我们额外开辟了 O(MN)的 visit 数组,同时栈的深度最大为 O(min(L,MN))。
* @date : 2021-05-04
*/
public class Solution79 {
public static void main(String[] args) {
char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}};
String word = "ABCB";
String word2 = "ABCCED";
Solution79 solution79 = new Solution79();
System.out.println(solution79.exist(board, word));
System.out.println(solution79.exist(board, word2));
}
public boolean exist(char[][] board, String word) {
//用于判断元素是否使用过
boolean[][] isVisit = new boolean[board.length][board[0].length];
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (dfs(board, isVisit, word, 0, i, j)) {
return true;
}
}
}
return false;
}
boolean dfs(char[][] board, boolean[][] isVisit, String word, int current, int r, int c) {
if (current == word.length()) {
return true;
}
if (r < 0 || c < 0) {
return false;
}
if (r >= board.length || c >= board[0].length) {
return false;
}
if (isVisit[r][c]) {
return false;
}
if (board[r][c] != word.charAt(current)) {
return false;
}
//元素不能重复使用
isVisit[r][c] = true;
boolean res = dfs(board, isVisit, word, current + 1, r, c - 1) ||
dfs(board, isVisit, word, current + 1, r, c + 1) ||
dfs(board, isVisit, word, current + 1, r - 1, c) ||
dfs(board, isVisit, word, current + 1, r + 1, c);
//如果以rc为起点无法找到,则重置为false
if (!res) {
isVisit[r][c] = false;
}
return res;
}
}