我正在尝试解决一个问题,其中以两个字符串作为参数,任务是确定第一个字符串是否包含制作第二个字符串所需的所有元素。我认为我可以通过从两个字符串创建字典来找到一个相当简单的解决方案,其中键是字符串中的字符,值是它们各自的出现次数。这是代码:
def scramble(s1, s2):
s1dict = {x: s1.count(x) for x in s1}
s2dict = {y: s2.count(y) for y in s2}
s3dict = {k:s2dict[k] for k in s2dict and s1dict[k] >= s2dict[k]}
return s3dict == s2dict
当我尝试将解决方案提交到Web挑战解释器时,它表示我的代码正在超时。我知道对于大型字符串,此解决方案会引起很多迭代……我可以采取什么方法来提高效率?
答案 0 :(得分:0)
def check_words(one, two):
# theses are characters the two strings have
# this prevents looping over the same character when checking counts latter
shared = set(one + two)
# these are the number of each share string the have in dict format
one_count = {letter: one.count(letter) for letter in shared}
two_count = {letter: two.count(letter) for letter in shared}
# confirm both strings posses the characters need to form them
if one_count == two_count:
print(True)
check_words("hello", "lehol")
答案 1 :(得分:0)
正如其他人所说,字典理解并不是天生的低效。如果您想加快解决方案的速度,就应该看看您的算法。
s1dict = {x: s1.count(x) for x in s1}
是一种获取s1
中所有字符计数的低效率方法。如果s1
的长度为N,则将迭代s1
N次,使其为O(N ^ 2)。如果您要自己实现该逻辑,它将看起来像这样:
s1dict = {}
for char1 in s1:
for char2 in s1:
if char2 == char1:
s1dict[char1] = s1dict.get(char1, 0) + 1
有一种方法可以获取O(N)时间的计数。
s1dict = {}
for char in s1:
s1dict[char] = s1dict.get(char, 0) + 1
或者,您可以使用collections.Counter
为您执行此操作:s1dict = collections.Counter(s1)
。
计算s3dict的方法实际上是无效的。无论如何,我也不认为词典理解是比较两个词典的最佳方法。您可以使用字典理解(all({k: s1dict.get(k, 0) >= v for k, v in s2dict.items()})
),但为什么不编写一个简单的循环呢?
for key, value in s2dict.items():
if s1dict.get(key, 0) < value:
return False
return True