我认为上述答案错过了关键点。我们有一个有 27 个维度的空间,第一个是长度,其他是每个字母的坐标。在那个空间里,我们有点,也就是词。一个词的第一个坐标是他的长度。对于每个字母维度,其他坐标是该字母在该单词中出现的次数。例如算盘、三角体、gaff、giraffe、麦克风、礁、 qar、abcdefghijklmnopqrstuvwxyz这些词都有坐标
[3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[6, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
[7, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[4, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[7, 1, 0, 0, 0, 1, 2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[4, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
具有坐标的集合的良好结构是R-tree或R*-Tree。给定您的集合 [x0, x1, ..., x26],您必须针对每个字母询问最多包含 xi 个字母的所有单词。您的搜索在 O(log N) 中,其中 N 是字典中的单词数。但是,您不想查看与您的查询匹配的所有单词中的最大单词。这就是为什么第一个维度很重要。
你知道最大单词的长度在0到X之间,其中X=sum(x_i, i=1..26)。您可以从 X 到 1 进行迭代搜索,但您也可以对查询的长度执行二进制搜索算法。您使用数组的第一个维度作为查询。你从 a=X 开始到 b=X/2。如果它们至少匹配,则从 a 搜索到 (a+b)/2,否则从 b 搜索到 b-(ab)/2=(3b-a)/2。你这样做,直到你有 ba=1。您现在拥有最大的长度以及所有具有此长度的匹配项。
该算法在渐近上比上述算法高效得多。时间复杂度为 O(ln(N)×ln(X))。实现取决于您使用的 R-tree 库。