假设 n 和 k 不是太大,这样这将适合内存:
有一个删除第一个字母的集合,一个删除第二个字母的集合,一个删除第三个字母的集合,等等。从技术上讲,这必须是从字符串到计数的映射。
遍历列表,只需将当前元素添加到每个映射(显然首先删除适用的字母)(如果它已经存在,将计数添加到 totalPairs 并将其加一)。
然后 totalPairs 是所需的值。
编辑:
复杂:
这应该是O(n.k.logn)
。
您可以使用使用散列的映射(例如HashMap
在 Java 中),而不是排序映射,以实现理论上的复杂性O(nk)
(尽管我通常发现哈希映射比基于树的排序映射要慢)。
改进:
对此的一个小改动是将前 2 个字母的映射删除为 2 个映射,一个删除第一个字母,一个删除第二个字母,第三个和第四个字母相同,依此类推。
然后将它们放入删除了 4 个字母的地图中,将这些放入删除了 8 个字母的地图中,依此类推,最多删除一半的字母。
其复杂性在于:
您对包含最大 k 个元素(每半个)的 2 个排序集进行 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)
(对于第 4 和第 5,值已经存在,因此增加)。
第三张地图:((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 个字母的映射到删除第 1 个和第 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 和第 5cd
已经存在,所以,不是生成上面的,而是将其添加到该地图中,如下所示:
(cd-{ {(bcd-1, dcd-1, ecd-1)}, {(acd-3)} }),
(dd-{ {(bdd-1)}, {(add-1)} }),
(cb-{ {(dcb-1)}, {(acb-1)} })