首先注意:抱歉我的图片没有分开。我是新成员,所以我没有足够的声誉点来发布超过一个超链接。
设M是一个n×n的数组(数学方阵)。
在M中,我需要能够找到具有限制的所有字符排列。排列不必是线性的,但是它们必须包含字符,使得每个字符与排列中的至少一个其他字符相邻。可接受排列的一个例子如下:
下面显示了不可接受的排列。
我已经得到了这么多:
我可以很容易地找到仅包含直线字符的排列:垂直线,水平线和对角线。我不确定如何详尽地找到所有剩余的排列。
我做过研究,但未能找到类似问题的解决方案。
非常感谢任何关于开发这种详尽算法的建议。
答案 0 :(得分:1)
如果考虑时间复杂性,可以立即想到一种算法,但可以进行优化。
在2x2阵列中的每个元素(或者如果你愿意,我们可以称之为矩阵),我们可以行进8个方向(北,东,东,东南,西南,西南,西北)。 / p>
算法的伪代码有点像这样(我假设按值传递,所以“current_string”是每个函数调用的新字符串):
find(position, direction, current_string){
new_letter = m[0, position + direction];
if(!current_string.Contains(new_letter)){
// We have not yet encountered this letter during the search.
// If letters occur more than once in the array, then you must
// assign an index to each position in the array instead and
// store which positions have been encountered along each
// search path instead.
current_string += new_letter;
find(position, (0, 1), current_string);
find(position, (1, 1), current_string);
find(position, (1, 0), current_string);
find(position, (1, -1), current_string);
find(position, (0, -1), current_string);
find(position, (-1, -1), current_string);
find(position, (-1, 0), current_string);
find(position, (-1, 1), current_string);
} else {
// This letter has been encountered during this path search,
// terminate this path search. See comment above if letters
// occur more than once in the matrix.
print current_string; // Print one of the found strings!
}
}
现在你需要添加一些检查,例如“在阵列范围之外的位置+方向,如果是这样,打印current_string并终止”。
上述算法的高级概念是以递归方式搜索所有可能的路径,当它们遇到自身时终止路径(就像蛇在游戏{3}}中死亡一样。)
如果使用散列来测试对当前字符串(按照行if(!current_string.Contains(new_letter)){
)的一个新字母的包含,这是通过分摊O(1)搜索,那么该算法的最坏情况运行时复杂度是线性的在矩阵中有可能的字符串数。即如果矩阵中有n个可能的字符串组合,则该算法需要大约cn步才能完成大n,其中c是一些常数。