Skip to content

Commit d58cfae

Browse files
committed
P79 Automaton
1 parent 6fd8a3c commit d58cfae

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

src/search/backtracking/P79WordSearch.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ private boolean inArea(char[][] board, int i, int j) {
3939
return (i >= 0 && j >= 0 && i < board.length && j < board[i].length);
4040
}
4141
// 解法2 (简洁)
42-
private boolean backtracking(char[][] board, int i, int j, String word, int charPos) {
42+
private boolean backtrackingOld(char[][] board, int i, int j, String word, int charPos) {
4343
char c = board[i][j];
4444
if (charPos == word.length() - 1) return c == word.charAt(charPos);
4545
if (c == '#' || c != word.charAt(charPos)) return false;
@@ -51,6 +51,21 @@ private boolean backtracking(char[][] board, int i, int j, String word, int char
5151
board[i][j] = c;
5252
return false;
5353
}
54+
// 最好的写法
55+
private boolean backtracking(char[][] board, int i, int j, String word, int charPos) {
56+
if (charPos == word.length()) return true;
57+
// 将判断移到此处来
58+
if (i < 0 || j < 0 || i >= board.length || j >= board[0].length) return false;
59+
char c = board[i][j];
60+
if (c == '#' || c != word.charAt(charPos)) return false;
61+
board[i][j] = '#';
62+
if (backtracking(board, i-1, j, word, charPos+1)) return true;
63+
if (backtracking(board, i, j-1, word, charPos+1)) return true;
64+
if (backtracking(board, i+1, j, word, charPos+1)) return true;
65+
if (backtracking(board, i, j+1, word, charPos+1)) return true;
66+
board[i][j] = c;
67+
return false;
68+
}
5469

5570
public boolean exist(char[][] board, String word) {
5671
if (board == null || board.length == 0 || word == null || word.length() == 0) return false;

src/search/backtracking/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# 回溯
2+
3+
回溯就是有规律的遍历,改变状态,然后再该回来状态(回溯)
4+
5+
**模版**
6+
参数:原始参数(题目必备的参数)、start(开始位置), cur(当前答案), ans(保存的所有答案)
7+
8+
Java中注意如果将当前答案添加到最终ans list时,要new一个新的对象
9+
```Java
10+
// 找到所有方案
11+
void findSolutions(n, other params) {
12+
if (found a solution) { // 找到一个答案
13+
// solutionsFound = solutionsFound + 1;
14+
addSolution(); // 将当前solution添加到solution list中
15+
// if (solutionsFound >= solutionTarget) :
16+
// System.exit(0);
17+
return
18+
}
19+
// 有的写不成循环,要分多个情况进行讨论;本质上循环就是多个情况,只不过写起来比较简单而已
20+
for (val = first to last) { // or start(开始位置参数) to last
21+
if (! isValid(val, n)) continue; // 剪枝
22+
applyValue(val, n); // 改变参数
23+
findSolutions(n+1, other params);
24+
removeValue(val, n); // 取消 改变参数
25+
}
26+
}
27+
```
28+
29+
> 还有一种方案是:将每一步的剪枝移动到循环的前部,让其 return false(见79题),具体采取哪种方案视情况而定
30+
31+
```Java
32+
// 一个方案是否存在
33+
boolean findSolutions(n, other params) {
34+
if (found a solution) {
35+
displaySolution();
36+
return true;
37+
}
38+
39+
for (val = first to last) { // or start(开始位置参数) to last
40+
if ( !isValid(val, n)) continue;
41+
applyValue(val, n);
42+
if (findSolutions(n+1, other params)) return true;
43+
removeValue(val, n);
44+
}
45+
return false;
46+
}
47+
```

0 commit comments

Comments
 (0)