https://leetcode-cn.com/problems/word-search/
/// 79. Word Search
/// Source : https://leetcode.com/problems/word-search/description/
///
/// 回溯法
/// 时间复杂度: O(m*n*m*n)
/// 空间复杂度: O(m*n)
public class Solution {
private int d[][] = {
{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
private int m, n;
private boolean[][] visited;
public boolean exist(char[][] board, String word) {
//if (board == null || word == null){
// throw new IllegalArgumentException("board or word can not be null!");
//}
m = board.length;
//if (m == 0){
// throw new IllegalArgumentException("board can not be empty.");
//}
n = board[0].length;
//if (n == 0){
// throw new IllegalArgumentException("board can not be empty.");
//}
visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (searchWord(board, word, 0, i, j)) {
return true;
}
}
}
return false;
}
private boolean inArea(int x, int y) {
return x >= 0 && x < m && y >= 0 && y < n;
}
// 从board[startx][starty]开始, 寻找word[index...word.size())
private boolean searchWord(char[][] board, String word, int index, int startx, int starty) {
//assert(inArea(startx,starty));
if (index == word.length() - 1){
return board[startx][starty] == word.charAt(index);
}
if (board[startx][starty] == word.charAt(index)) {
visited[startx][starty] = true;
// 从startx, starty出发,向四个方向寻
for (int i = 0; i < 4; i++) {
int newx = startx + d[i][0];
int newy = starty + d[i][1];
if (inArea(newx, newy) && !visited[newx][newy] && searchWord(board, word, index + 1, newx, newy)) {
return true;
}
}
visited[startx][starty] = false;
}
return false;
}
//public static void main(String args[]) {
// char[][] b1 = {
{'A', 'B', 'C', 'E'},
// {'S', 'F', 'C', 'S'},
// {'A', 'D', 'E', 'E'}};
//
// String words[] = {"ABCCED", "SEE", "ABCB"};
// for (int i = 0; i < words.length; i++)
// if ((new Solution()).exist(b1, words[i]))
// System.out.println("found " + words[i]);
// else
// System.out.println("can not found " + words[i]);
//
// // ---
//
// char[][] b2 = {
{'A'}};
// if ((new Solution()).exist(b2, "AB"))
// System.out.println("found AB");
// else
// System.out.println("can not found AB");
//}
}
class Solution {
//四个方向
//上 右 下 左
private int[][] dir = {
{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
private boolean[][] visited;
//行数
private Integer m;
//列数
private Integer n;
public boolean exist(char[][] board, String word) {
m = board.length;
n = board[0].length;
visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (dfs(i, j, 0, board, word)){
return true;
}
}
}
return false;
}
private boolean dfs(int x, int y, int index, char[][] board, String word) {
if (index == word.length() - 1) {
return word.charAt(index) == board[x][y];
}
if (board[x][y] == word.charAt(index)) {
visited[x][y] = true;
for (int i = 0; i < 4; i++) {
int disX = x + dir[i][0];
int disY = y + dir[i][1];
if (areYouOk(disX, disY) && visited[disX][disY] == false) {
if (dfs(disX, disY, index + 1, board, word)){
return true;
}
//return dfs(disX, disY, index + 1, board, word);
}
}
visited[x][y] = false;
}
return false;
}
/**
* 返回(x,y)是否越界
* @param x 行
* @param y 列
*/
private boolean areYouOk(int x, int y) {
return x >= 0 && x < m && y >= 0 && y < n;
}
//public static void main(String[] args) {
// char arr[][] = {
{'a','a'}};
// String str = "aaa";
// //false
// System.out.println(new Solution().exist(arr, str));
//}
}