假设我有一个不同长度的字符串数组
可以假设字符串没有重复字符
使用强力算法,我可以找到具有最多相同字母的字符串对(顺序无关紧要 - 例如," ABCDZFW"" FBZ"有3个相等的字母)在n平方的时间内
有没有更有效的方法呢?
尝试:我尝试使用trie数据结构来考虑解决方案,但这不会起作用,因为trie只会将具有相似前缀的字符串组合在一起。
答案 0 :(得分:2)
我可以找到具有最多相同数量的字符串对 字母(顺序无关紧要 - 例如,“ABCDZFW”和“FBZ”都有 n平方时间内有3个相同的字母。
我认为你不能将字符串比较本身O(max(length(s1), length(s2)))
与O(n^2)
循环一起检查所有对。但是,您可以在某种程度上优化字符串的比较。
正如你所提到的,字符串没有重复,我假设字符串根据你的输入只包含大写字母。所以,它变成每个字符串只能是26个字符。
对于每个字符串,我们可以使用位掩码。对于字符串的每个字符,我们可以设置相应的位1.例如:
ABCGH
11000111 (from LSB to MSB)
因此,n
字符串有n
位掩码。
现在,您可以使用O(n^2)
循环检查所有可能的字符串对,并通过ANDing两个相应的掩码比较字符串,并检查设置位数(汉明重量)。显然,这是对您的版本的改进,因为现在优化了字符串比较 - 只有两个32位整数之间的AND运算,这是一个O(1)
操作。
例如对于任何两个字符串,比较将是:
ABCDG
ABCEF
X1 = mask(ABCDG) => 1001111
X2 = mask(ABCEF) => 0110111
X1 AND X2 => 0000111
hamming weight(0000111) => 3 // number of set bits
<#2>方式#2
现在,一个观察结果是相同类型的AND位是1.因此对于每个掩码,我们将尝试最大化两个字符串掩码的AND值的Hamming weight(设置位总数)作为字符串大多数匹配的字符具有相同的位1,并且这两个掩码的“与”将使这些位为1。
现在使用所有掩码构建Trie - 根据相应的位设置或不设置trie的每个节点将保持0或1。从MSB或LSB插入每个掩码。在将i
掩码插入Trie(已经持有i - 1
掩码)之前,我们将通过转到相同位的分支来查询以尝试最大化AND的汉明权重(以使最后的AND位变为1) )和也对着相对位的分支,因为在后面的级别中,您可能会在此分支中获得更多的设置位。
关于这个Trie部分,为了获得精美的图片解释,你可以找到一个类似的线程here(这适用于XOR)。
在最坏的情况下,我们需要遍历许多trie分支以最大化汉明重量。在最坏的情况下,它将需要6 * 10^6
次操作(在典型的机器中需要约1秒),而且我们还需要额外的空间来构建特里。但是说字符串的总数是10^5
,那么对于O(n^2)
算法,它会花费10^10
次操作 - 所以trie方法仍然要好得多。
如果您遇到实施问题,请告诉我。不幸的是,只有当你是C / C ++或Java人时,我才能帮你解决代码问题。
感谢@JimMischel指出一个重大缺陷。我先稍微误解了这句话。