-
Notifications
You must be signed in to change notification settings - Fork 23
/
Word Search.java
executable file
·130 lines (102 loc) · 3.74 KB
/
Word Search.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
M
tags: Array, Backtracking, DFS
#### DFS, Backtracking:
- 找到开头的字母, 然后recursively DFS 去把word串到底:
- 每到一个字母, 朝四个方向走, 之中一个true就可以.
- Note:每次到一个字母,mark一下'#'. 4个path recurse回来后,mark it back.
#### Note: other ways of marking visited:
- 用一个boolean visited[][]
- Use hash map, key = x@y
```
/*
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
Example:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
*/
/*
Thoughts:
Word Search II 简化版: 只有DFS, 没有words的结构优化
1. DFS (board, x, y)
2. Backtracking: mark visited item '#'
*/
class Solution {
int[] dx = {0, 0, 1, -1};
int[] dy = {1, -1, 0, 0};
public boolean exist(char[][] board, String word) {
if (board == null || word == null || word.length() == 0) return false;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (dfs(board, word, i, j, 0)) return true;
}
}
return false;
}
private boolean dfs(char[][] board, String s, int x, int y, int index) {
if (validate(board, x, y, s.charAt(index))) return false;
if (index == s.length() - 1) return true;
board[x][y] = '#';
for (int i = 0; i < dx.length; i++) {
if (dfs(board, s, x + dx[i], y + dy[i], index + 1)) return true;
}
board[x][y] = s.charAt(index);
return false;
}
private boolean validate(char[][] board, int x, int y, char c) {
return x < 0 || x >= board.length || y < 0 || y >= board[0].length
|| board[x][y] != c || board[x][y] == '#';
}
}
/*
Thoughts:
1. find starting index i,j
2. Start divde&&conqure: each iteration.
In each interation: make sure board[i][j] == word.charAt(currentCheckingIndex); If not match, return false and terminate the interation
3. Therefore, if (start) == word.length(), that means all previous-start indexes are matched, so we have a match; return true in this case.
Note: if can use boolean || boolean || boolean, use it and save processing power: once one boolean works, it won't process the rest || elements
*/
public class Solution {
public boolean exist(char[][] board, String word) {
if (word == null || word.length() == 0) {
return true;
}
if (board == null) {
return false;
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == word.charAt(0)) {
boolean rst = search(board, word, i, j, 0);
if (rst) {
return true;
}
}
}
}
return false;
}
public boolean search(char[][] board, String word, int i, int j, int start) {
if (start == word.length()) {
return true;
}
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != word.charAt(start)) {
return false;
}
board[i][j] = '#';
boolean rst = search(board, word, i, j - 1, start + 1)
|| search(board, word, i, j + 1, start + 1)
|| search(board, word, i + 1, j, start + 1)
|| search(board, word, i - 1, j, start + 1);
board[i][j] = word.charAt(start);
return rst;
}
}
```