假设 n 和 k 不太大,这样就可以放入内存:
有一个删除第一个字母的集合,一个删除第二个字母的集合,一个删除第三个字母的集合,等等。从技术上讲,这必须是从字符串到计数的映射。
遍历列表,只需将当前元素添加到每个映射(显然首先删除适用的字母)(如果它已经存在,将计数添加到 totalPairs 并将其加一)。
那么 totalPairs 就是想要的值。
编辑:
复杂性:
这应该是O(n.k.logn)。
您可以使用使用散列的映射(例如 Java 中的 HashMap),而不是排序映射,其理论复杂度为 O(nk)(尽管我通常发现哈希映射比排序树慢基于地图)。
改进:
对此的一个小改动是将前 2 个字母的映射删除为 2 个映射,一个删除第一个字母,一个删除第二个字母,第三个和第四个字母相同,依此类推。
然后将它们放入删除了 4 个字母的地图中,将这些放入删除了 8 个字母的地图中,依此类推,最多删除一半的字母。
这个复杂度是:
您对 2 个包含最大 k 个元素(每半个元素)的已排序集合进行 2 次查找。
对于这些中的每一个,您再次对 2 个排序集进行 2 次查找(每个季度)。
所以查找次数是 2 + 4 + 8 + ... + k/2 + k,我相信是O(k)。
我在这里可能是错的,但是,最坏的情况是,任何给定地图中的元素数量是n,但这会导致所有其他地图只有 1 个元素,所以仍然是O(logn),但是对于每个n(不是每个n.k)。
所以我认为是O(n.(logn + k))。
.
编辑 2:
我的地图示例(未改进):
(x-1) 表示x 映射到1。
假设我们有abcd, abdd, adcb, adcd, aecd。
第一张地图是(bcd-1), (bdd-1), (dcb-1), (dcd-1), (ecd-1)。
第二张地图是(acd-3), (add-1), (acb-1)(对于第四张和第五张,值已经存在,所以递增)。
第三张地图:(abd-2), (adb-1), (add-1), (aed-1)(第二张已经存在)。
第四张地图:(abc-1), (abd-1), (adc-2), (aec-1)(第四张已经存在)。
totalPairs = 0
对于第二张地图 - acd,第四张我们加 1,第五张我们加 2。
totalPairs = 3
对于第三张地图 - abd,对于第二张,我们加 1。
totalPairs = 4
对于第四张地图 - adc,对于第四张,我们加 1。
totalPairs = 5.
改进地图的部分示例:
与上述相同的输入。
前 2 个字母的映射被移除到第一个和第二个字母被移除的映射:
(cd-{ {(bcd-1)}, {(acd-1)} }),
(dd-{ {(bdd-1)}, {(add-1)} }),
(cb-{ {(dcb-1)}, {(acb-1)} }),
(cd-{ {(dcd-1)}, {(acd-1)} }),
(cd-{ {(ecd-1)}, {(acd-1)} })
上面是一个映射,由一个元素cd映射到2个映射,一个包含一个元素(bcd-1),另一个包含(acd-1)。
但是对于第 4 个和第 5 个cd 已经存在,所以,与其生成上述内容,不如将其添加到该地图中,如下所示:
(cd-{ {(bcd-1, dcd-1, ecd-1)}, {(acd-3)} }),
(dd-{ {(bdd-1)}, {(add-1)} }),
(cb-{ {(dcb-1)}, {(acb-1)} })