package leecode;
/**
* 剑指 Offer 12. 矩阵中的路径
*
* 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
*
* 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
*
*
*
* @author Tang
* @date 2021/12/16
*/
public class Exist {
char[][] board;
char[][] hasChoose;
char[] words;
/**
* 回溯法
* 把word逐个拆开 挨个判断
* 1.先顺序遍历二维数组找到首个word
* 2.以下一个word,和上一个word的横纵坐标进行递归。 分别判断他的上下左右是否有合适的下一个word
* 3.有合适的word则加入hasChoose,避免重复占用元素
* 4.撤销选择 元素移出hasChoose
*
* @param board
* @param word
* @return
*/
public boolean exist(char[][] board, String word) {
this.board = board;
//单词数组
words = word.toCharArray();
//保存已选择过的位置
//选择过为1
hasChoose = new char[board.length][board[0].length];
//遍历整个二维数组
//找到第一个字母位置执行递归
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(board[i][j] == words[0]) {
hasChoose[i][j] = 1;
if(track(1, i, j)) {
return true;
}
hasChoose[i][j] = 0;
}
}
}
return false;
}
/**
* 目的;判断上一个选择元素的上下左右位置是否有合适的word
*
* @param i 当前要找的words索引 words[i]
* @param rowIndex 上一个选择元素是第几行
* @param heightIndex 上一个选择元素第几列
*/
private boolean track(int i, int rowIndex, int heightIndex) {
//所有word都找完了 成功结束
if(i >= words.length) {
return true;
}
//分别上下左右走一遍
return checkAndProcess(i, rowIndex - 1, heightIndex) ||
checkAndProcess(i, rowIndex + 1, heightIndex) ||
checkAndProcess(i, rowIndex, heightIndex - 1) ||
checkAndProcess(i, rowIndex, heightIndex + 1);
}
/**
* 判断该位置是否符合word条件
* 如果符合 执行递归
* 递归后撤销选择
*
* @param rowIndex
* @param heightIndex
*/
private boolean checkAndProcess(int i, int rowIndex, int heightIndex) {
if(rowIndex >= board.length || rowIndex < 0 ||
heightIndex >= board[rowIndex].length ||heightIndex < 0 ) {
return false;
}
//递归前做出选择
//判断board[rowIndex][heightIndex]是否是合适word
//如果不为word或者已经被占用过了
if(board[rowIndex][heightIndex] != words[i] || hasChoose[rowIndex][heightIndex] == 1) {
return false;
}
hasChoose[rowIndex][heightIndex] = 1;
//执行递归
if(track(i + 1, rowIndex, heightIndex)){
return true;
}
//递归后撤销选择
hasChoose[rowIndex][heightIndex] = 0;
return false;
}
public static void main(String[] args) {
// char[][] board = {
// {'A', 'B', 'C', 'E'},
// {'S', 'F', 'C', 'S'},
// {'A', 'D', 'E', 'E'}
// };
char[][] board = {
{'a'},
{'b'}
};
System.out.println(new Exist().exist(board, "ba"));
}
}