我解决了一个难题,但需要优化我的解决方案。难题说我要取一个字符串S,查找其字符的所有排列,对结果进行排序,然后返回该列表中出现的其中一个基于索引的索引号S。优化一种查找字符串的所有排列的方法
例如,字符串'bac'出现在其排列列表中的第3个位置:['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
。
我的问题是,谜题限制我的执行时间为500毫秒。其中一个测试用例通过“BOOKKEEPER”作为输入,需要4.2秒才能完成。
我采用了一种(可能是天真的)动态编程方法,使用memoization,使用一个由特定字符集的特定排列组成的字典,但这还不够。
我的瓶颈是什么?
我正在分析,看看我能否回答我自己的问题,但我邀请那些直接看到问题的人帮助我理解我是如何减缓这种情况的。
编辑:我的解决方案似乎超过itertools.permutations
。 10秒以上输入“问题”。但公平地说,这包括时间打印,所以这可能不是一个公平的比较。即便如此,我宁愿提交具有竞争力表现的手写解决方案,以了解为什么我的选择不如选择模块。
memo = {}
def hash(word):
return ''.join(sorted(word))
def memoize(word, perms):
memo[hash(word)] = perms
return perms
def permutations(word, prefix = None):
"""Return list of all possible permutatons of given characters"""
H = hash(word)
if H in memo:
return [s if prefix is None else prefix + s for s in memo[H]]
L = len(word)
if L == 1:
return [word] if prefix is None else [prefix + word]
elif L == 2:
a = word[0] + word[1]
b = word[1] + word[0]
memoize(word, [a, b])
if prefix is not None:
a = prefix + a
b = prefix + b
return [a, b]
perms = []
for i in range(len(word)):
perms = perms + permutations(word[:i] + word[i+1:], word[i])
memoize(word, perms)
return [prefix + s for s in perms] if prefix is not None else perms
def listPosition(word):
"""Return the anagram list position of the word"""
return sorted(list(set(permutations(word)))).index(word) + 1
print listPosition('AANZ')
'itertools.permutations'如何执行?请参阅'timeit'模块或IPython魔术'%timeit' –
@WayneWerner哦,忘记提及了。更糟的是。 10s +用于输入“问题” –
@WayneWerner请参阅编辑 –