从CodeFights解决以下问题:
给定两个字符串,找到它们之间的公共字符数。 对于s1 =“aabcc”和s2 =“adcaa”,输出应为 commonCharacterCount(s1,s2)= 3。
字符串有3个常用字符 - 2“a”和1“c”。
我接近它的方式,每当我考虑到一封信时,我都想取消它,以免再次计算它。我知道字符串是不可变的,即使使用诸如.replace()
之类的方法(replace()方法返回字符串的副本,也没有更改实际字符串)。
为了改变所说的string
我在开始时倾向于做的只是将其传递给list(mystring)
的列表,然后改变它。
问题 ...以下哪项更有效?考虑到选项B一遍又一遍地完成,最坏的情况是字符串相等并且匹配匹配。同时选项A发生一次。
选项A)
list(mystring)
选项B)
mystring = mystring.replace(letterThatMatches, "")
答案 0 :(得分:7)
在您找到的每个元素的字符串上调用replace
的想法根本不是一个好主意:它需要 O(n)来执行此操作。如果对另一个字符串中的每个字符执行此操作,将生成 O(m×n)算法,其中 m 第一个字符串的字符数,并且 n 第二个字符串中的字符数。
您可以简单地使用两个Counter
,然后计算两者中的最小值,然后计算计数的总和。像:
from collections import Counter
def common_chars(s1,s2):
c1 = Counter(s1) # count for every character in s1, the amount
c2 = Counter(s2) # count for every character in s2, the amount
c3 = c1 & c2 # produce the minimum of each character
return sum(c3.values()) # sum up the resulting counts
或作为单行:
def common_chars(s1,s2):
return sum((Counter(s1) & Counter(s2)).values())
如果字典查找可以在 O(1)中完成(通常适用于普通情况),这是一个 O(m + n)算法:然后分别在 O(m)和 O(n)中进行计数,并计算不同字符数(最多 O)的最小运行次数( max(m,n))。最后取总和再次是 O(max(m,n))操作。
对于样本输入,结果如下:
>>> common_chars("aabcc","adcaa")
3