79. Word Search (backtracking)
Last updated
Last updated
visited = new boolean[board.length][board[0].length];class Solution {
public boolean exist(char[][] board, String word) {
for (int i = 0 ; i < board.length; i++) {
for (int j = 0; j < board[i].length;j++) {
if (board[i][j] == word.charAt(0) && dfs(board, i, j, 0, word)) {
return true; // if find first char, and dfs search ok
}
}
}
return false;
}
private boolean dfs(char[][] board,int i, int j, int count, String word) {
if (count == word.length()) { // length equals to ori word, good!
return true;
}
if (i < 0 || i >= board.length || j < 0 || j >= board[i].length
|| board[i][j] != word.charAt(count)) {
return false; // outboud
}
char temp = board[i][j]; // backtracking
board[i][j] = ' '; // set to empty to represent used
// use or, so can't use dirs[]
boolean result =
dfs(board, i + 1, j, count+1, word) ||
dfs(board, i - 1, j, count+1, word) ||
dfs(board, i, j + 1, count+1, word) ||
dfs(board, i, j - 1, count+1, word);
board[i][j] = temp; // add back
return result;
}
}class Solution {
private static final int[][] DIRS = {{0,1},{0,-1},{1,0},{-1,0}};
public boolean exist(char[][] grid, String word) {
if (!pruning(grid, word)) {
return false;
}
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == word.charAt(0) && dfs(grid, word, 0, i, j)) {
return true;
}
}
}
return false;
}
private boolean pruning(char[][] grid, String word) {
int m = grid.length;
int n = grid[0].length;
// pruning: case 1: not enough characters in board
if (word.length() > m * n) {
return false;
}
// pruning: case 2: board does not contain characters or enough characters that word contains
Map<Character, Integer> count = new HashMap<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int temp = count.getOrDefault(grid[i][j], 0);
count.put(grid[i][j], temp + 1);
}
}
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (!count.containsKey(c)) {
return false; // cant find word's char in hashmap
} else { // remove count one by one, because word maybe duplicate
int temp = count.get(c);
if (temp == 1) {
count.remove(c);
} else {
count.put(c, temp - 1);
}
}
}
return true;
}
private boolean dfs(char[][] grid, String word, int start, int i, int j) {
if (start == word.length()) {
return true;
}
if (!isValid(grid, i, j) || word.charAt(start) != grid[i][j]) {
return false;
}
char temp = grid[i][j];
grid[i][j] = ' ';
boolean result = false;
for (int[] dir : DIRS) {
result = dfs(grid, word, start + 1, i + dir[0], j + dir[1]);
if (result) { // find 就 break
break;
}
}
grid[i][j] = temp;
return result;
}
private boolean isValid(char[][] grid, int i, int j) {
return i >= 0 && i < grid.length && j >= 0 & j < grid[0].length;
}
}
/*
dfs search
how to ?
put first word in dfs search, then 4 direction
dfs() {
if (start == word.length()) {
return true;
}
if (4 direction) {
get result
if (not ok return false)
}
return result
}
*/class Solution {
private static final int[][] DIRS = {{0,1}, {0,-1}, {1,0}, {-1,0}};
public boolean exist(char[][] board, String word) {
int m = board.length;
int n = board[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == word.charAt(0) && dfs(board, word, 0, i, j, new boolean[m][n])) {
return true;
}
}
}
return false;
}
private boolean dfs(char[][] board, String word, int start, int i, int j, boolean[][] visited) {
if (start == word.length()) {
return true;
}
if (!inArea(board, i, j) || visited[i][j] || word.charAt(start) != board[i][j]) {
return false;
}
visited[i][j] = true;
for (int[] dir : DIRS) {
int x = i + dir[0];
int y = j + dir[1];
if (dfs(board, word, start+1, x, y, visited)) {
return true;
}
}
visited[i][j] = false;
return false;
}
private boolean inArea(char[][] board, int x, int y) {
return x >= 0 && x < board.length && y >=0 && y < board[0].length;
}
}
/*
needs match word[0] to start
for (board)
if (ij == word[0]) {
dfs(start, i, j, )
}
retur
start == word.length
*/class Solution {
private static final int[][] DIRS = {{0,1}, {0,-1}, {1,0}, {-1,0}};
public boolean exist(char[][] board, String word) {
int m = board.length;
int n = board[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == word.charAt(0) && dfs(board, word, 0, i, j)) {
return true; // 為什麼都找到第一個字了, 還要傳 index 0 進去?
} // 因為 mark 是在 dfs 裡面做的, backtracking 也是
}
}
return false;
}
private boolean dfs(char[][] board, String word, int start, int i, int j) {
if (start == word.length()) {
return true;
}
if (!inArea(board, i, j) || word.charAt(start) != board[i][j]) {
return false;
}
char temp = board[i][j];
board[i][j] = ' ';
for (int[] dir : DIRS) {
int x = i + dir[0];
int y = j + dir[1];
if (dfs(board, word, start+1, x, y)) {
return true;
}
}
board[i][j] = temp;
return false;
}
private boolean inArea(char[][] board, int x, int y) {
return x >= 0 && x < board.length && y >=0 && y < board[0].length;
}
}