题目描述

思路
- DFS
- DFS的过程中,如果当前char能对的上word中的char,则继续dfs,否则停止。
- 当凑齐了word,返回true。怎么判断凑齐了?dfs函数中传一个k来记录index。

Visited array, early pruning
class Solution {
public boolean exist(char[][] board, String word) {
int m = board.length, n = board[0].length;
if (canPruneEarly(board, word)) {
return false;
}
boolean[][] visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == word.charAt(0)) {
if (dfs(board, i, j, 0, word, visited)) {
return true;
}
}
}
}
return false;
}
public boolean dfs(char[][] board, int i, int j, int cur, String word, boolean[][] visited) {
int m = board.length, n = board[0].length;
if (i >= m || i < 0 || j >= n || j < 0) {
return false;
}
if (visited[i][j]) {
return false;
}
if (board[i][j] != word.charAt(cur)) {
return false;
}
if (cur == word.length() - 1) {
return true;
}
visited[i][j] = true;
boolean a = dfs(board, i + 1, j, cur + 1, word, visited);
boolean b = dfs(board, i - 1, j, cur + 1, word, visited);
boolean c = dfs(board, i, j + 1, cur + 1, word, visited);
boolean d = dfs(board, i, j - 1, cur + 1, word, visited);
visited[i][j] = false;
return (a || b || c || d);
}
private boolean canPruneEarly(char[][] board, String word) {
int m = board.length, n = board[0].length;
if (m * n < word.length()) {
return true;
}
int[] freqBoard = new int[128];
int[] freqWord = new int[128];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
freqBoard[board[i][j]]++;
}
}
for (char c : word.toCharArray()) {
freqWord[c]++;
}
for (int c = 0; c < 128; c++) {
if (freqWord[c] > freqBoard[c]) {
return true;
}
}
return false;
}
}
剪枝
class Solution {
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (dfs(board, i, j, word, 0)) {
return true;
}
}
}
return false;
}
public boolean dfs(char[][] board, int i, int j, String s, int k) {
int n = board.length, m = board[0].length;
if (i > n - 1 || i < 0 || j > m - 1 || j < 0 || board[i][j] != s.charAt(k)) {
return false;
}
if (k == s.length() - 1) {
return true;
}
board[i][j] = '*';
boolean flag = (
dfs(board, i, j + 1, s, k + 1) ||
dfs(board, i, j - 1, s, k + 1) ||
dfs(board, i + 1, j, s, k + 1) ||
dfs(board, i - 1, j, s, k + 1)
);
board[i][j] = s.charAt(k);
return flag;
}
}
未剪枝
class Solution {
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (dfs(board, i, j, word, 0)) {
return true;
}
}
}
return false;
}
public boolean dfs(char[][] board, int i, int j, String s, int k) {
int n = board.length, m = board[0].length;
if (i > n - 1 || i < 0 || j > m - 1 || j < 0 || board[i][j] != s.charAt(k)) {
return false;
}
if (k == s.length() - 1) {
return true;
}
board[i][j] = '*';
boolean l = dfs(board, i, j + 1, s, k + 1);
boolean r = dfs(board, i, j - 1, s, k + 1);
boolean u = dfs(board, i + 1, j, s, k + 1);
boolean d = dfs(board, i - 1, j, s, k + 1);
board[i][j] = s.charAt(k);
return l || r || u || d;
}
}
未剪枝2
class Solution {
boolean flag = false;
public boolean exist(char[][] board, String word) {
int m = board.length, n = board[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dfs(board, word, i, j, 0);
if (flag) {
return true;
}
}
}
return false;
}
public void dfs(char[][] board, String word, int i, int j, int index) {
if (i < 0 || j < 0 || i >= board.length || j >= board[0].length || word.charAt(index) != board[i][j]) {
return;
}
if (index == word.length() - 1) {
flag = true;
return;
}
char tmp = board[i][j];
board[i][j] = '@';
dfs(board, word, i + 1, j, index + 1);
dfs(board, word, i - 1, j, index + 1);
dfs(board, word, i, j + 1, index + 1);
dfs(board, word, i, j - 1, index + 1);
board[i][j] = tmp;
}
}