问题:输入是由一些字母构成的一个二维数组以及一组单词组成,目标是要找出字谜中的单词,这些单词可能是水平、垂直或演对角线上任何方向放置的。
求解如下:

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
var direction = [[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,-1],[1,-1],[-1,1]];
var input = ['t h i s','w a t s','o a h g','f g d t'];
var i,j,k,l,m,n;
var len;
var results = {};
var matrix = [];
// 将输入转换为矩阵
for (i = 0, len = input.length;i < len; i++) {
matrix.push(input[i].split(' '));
}
console.log(matrix);
var words = ['this', 'two', 'fat', 'that'];
for (j = 0; j < matrix.length; j++) {
for (k = 0; k < matrix[j].length;k++) {
var letter = matrix[j][k];
console.log('letter: ' + letter);
for (m = 0; m < direction.length;m++) {
var dirc = direction[m];
console.log('current direction is: ' + dirc);
for (l = 0; l < words.length; l++) {
var word = words[l];
// 如果单词首字母与矩阵元素匹配,则查询其各个方向
if (word[0] == letter) {
console.log(word + ' first character: ' + word[0]);
var x = j, y = k;
var temp = [];
<!-- 在这里检查矩阵边界,由于是从0开始的,所以是要小于matrix的长度,而不是小于等于 -->
for (n = 0; n < word.length && x >= 0 && x < matrix.length &&
y >= 0 && y < matrix[j].length && word[n] == matrix[x][y];
n++, x += dirc[0], y += dirc[1]) {
console.log('matrix[' + x +']['+ y +']: ' + matrix[x][y]);
temp.push([x,y]);
}
if (word.length == temp.length) {
results[word] = temp;
}
}
}
}
}
}
for (var z = 0; z < words.length; z++) {
console.log(words[z] + '\' result: ')
console.log(results[words[z]]);
}

这个解法是检查每一个有序三元组(行、列、方向),验证是否有单词存在。如上,嵌套了大量的for循环,但这是最直观的解法。
可以学习到的思路是:如何处理矩阵中8个方向的遍历,我们使用代表8个方向是坐标的加减来作各个方向上的移动,然后检查边界即可。

也可以这样,对于每一个尚未越出谜板边缘的有序四元组(行、列、方向、字符数),我们可以测试是否所指的单词在单词表上。这也会导致大量嵌套的for循环。如果在任意单词中的最大字符数已知,那么该算法有可能节省一些时间。