算法记录
LeetCode 题目:
给定一个 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
说明
一、题目
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
二、分析
- DFS暴力搜就行,但是最好剪枝,否则容易超时。
- 对搜过的做一个标记,回溯时将标记清除
- 分析一下题目,首字母应该可以从矩阵任意地方开始
- 用一个标记 控制 DFS的深度
class Solution {
boolean[][] flag;
public boolean exist(char[][] board, String word) {
// 路径标记
flag = 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, word, 0, i, j)) {
return true;
}
}
}
return false;
}
boolean DFS(char[][] board, String word, int index, int x, int y) {
boolean res = false;
// 递归搜索过程中 出现 不等 直接返回
if (board[x][y] != word.charAt(index)) {
return false;
} else if (index == word.length()-1) { // 当递归的深度达到字符串长度 index下标
return true;
}
flag[x][y] = true; // 标记走过的路
int[][] four = {{x + 1, y}, {x - 1, y}, {x, y-1}, {x, y+1}};
for (int i = 0; i < four.length; i++) {
int nx = four[i][0], ny = four[i][1];
if (nx < 0 || ny < 0 || nx > board.length-1 || ny > board[0].length-1) {
continue;
} else if (flag[nx][ny]) {
continue;
} else {
res = DFS(board, word, index+1, nx, ny);
if (res) {
break;
}
}
}
flag[x][y] = false;
return res;
}
}
总结
纯DFS的题目,注意一下剪枝就好了