-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathQ12_PathInMatrix.java
114 lines (94 loc) · 4.02 KB
/
Q12_PathInMatrix.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
package chapter2;
import org.junit.Assert;
import org.junit.Test;
import java.util.LinkedList;
/**
* 题目:请设计一个函数,、用来判断在一个矩阵中是否存在一条包含某
* 字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以
* 在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,
* 那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条
* 字符串"bfce”的路径(路径中的字母用下画线标出但矩阵中不包含字
* 符串"abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第
* 二个格子之后,路径不能再次进入这个格子。
* {'a', 'b', 't', 'g'},
* {'c', 'f', 'c', 's'},
* {'j', 'd', 'e', 'h'}
*
* @author flying
*/
public class Q12_PathInMatrix {
/**
* 思路:通过一个 Linked 存放 trace,trace 中有三个信息,i,j 坐标,以及下一个应该是它的上下左右四个周边节点的哪一个。
* 0 表示还没有访问过下一个节点,1 表示已经访问过上节点,2表示已经访问过左边的节点,3表示已经访问过下边的节点,
* 4 表示已经访问过左边的节点。
* @return null 表示找不到一条 trace。
*/
private LinkedList<int[]> pathInMatrix(char[][] matrix, char[] path) {
if (matrix == null || matrix.length == 0) {
return null;
}
LinkedList<int[]> trace = new LinkedList<>();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == path[0]) {
trace.add(new int[] {i, j, 0});
while (!trace.isEmpty()) {
if (trace.size() == path.length) {
return trace;
}
int [] lastPos = trace.getFirst();
int failure = lastPos[2]++;
if (failure == 4) {
trace.removeFirst();
continue;
}
int nextPosI = lastPos[0] + (failure == 0 ? -1 : failure == 2 ? 1 : 0);
int nextPosJ = lastPos[1] + (failure == 1 ? 1 : failure == 3 ? -1 : 0);
if (validPos(matrix, nextPosI, nextPosJ) && matrix[nextPosI][nextPosJ] == path[trace.size()]) {
trace.push(new int[] {nextPosI, nextPosJ, 0});
}
}
}
}
}
return null;
}
private boolean validPos(char[][] matrix, int i, int j) {
if (i < 0 || i >= matrix.length) {
return false;
}
if (j < 0 || j >= matrix[i].length) {
return false;
}
return true;
}
private boolean checkTrace(char[][] matrix, LinkedList<int[]> trace, char[] target) {
if (trace == null || trace.size() != target.length) {
return false;
}
int i = target.length - 1;
for (int[] point : trace) {
if (matrix[point[0]][point[1]] != target[i--]) {
return false;
}
}
return true;
}
@Test
public void test() {
char[][] matrix = new char[][] {
{'a', 'b', 't', 'g'},
{'c', 'f', 'c', 's'},
{'j', 'd', 'e', 'h'}
};
char[] target = new char[] {'a', 'b', 't', 'g'};
LinkedList<int[]> trace = pathInMatrix(matrix, target);
Assert.assertTrue(checkTrace(matrix, trace, target));
target = new char[] {'a', 'c', 'f', 'd','e','c','t','g','s','h'};
trace = pathInMatrix(matrix, target);
Assert.assertTrue(checkTrace(matrix, trace, target));
target = new char[] {'a', 'b', 't', 'g', 'c','t','g','s','h'};
trace = pathInMatrix(matrix, target);
Assert.assertFalse(checkTrace(matrix, trace, target));
}
}