简体   繁体   English

需要减少这个function中的递归调用次数

[英]Need to reduce the number of recursive calls in this function

The problem is given a string S and an integer k<len(S) we need to find the highest string in dictionary order with any k characters removed but maintaining relative ordering of string.问题是给定一个字符串 S 和一个 integer k<len(S) 我们需要找到字典顺序中最高的字符串,删除任何 k 个字符但保持字符串的相对顺序。

This is what I have so far:这是我到目前为止所拥有的:

def allPossibleCombinations(k,s,strings):
    if k == 0:
       
        strings.append(s)
        return strings
    
    for i in range(len(s)):
        new_str = s[:i]+s[i+1:]
        strings = allPossibleCombinations(k-1, new_str, strings)
        
    return strings

def stringReduction(k, s):
    strings = []
    combs = allPossibleCombinations(k,s, strings)
    return sorted(combs)[-1]

This is working for a few test cases but it says that I have too many recursive calls for other testcases.这适用于一些测试用例,但它说我对其他测试用例有太多递归调用。 I don't know the testcases.我不知道测试用例。

This should get you started -这应该让你开始 -

from itertools import combinations

def all_possible_combinations(k = 0, s = ""):
  yield from combinations(s, len(s) - k)

Now for a given k=2 , and s="abcde" , we show all combinations of s with k characters removed -现在对于给定的k=2s="abcde" ,我们显示s所有组合并删除了k个字符 -

for c in all_possible_combinations(2, "abcde"):
  print("".join(c))

# abc
# abd
# abe
# acd
# ace
# ade
# bcd
# bce
# bde
# cde

it says that I have too many recursive calls for other testcases它说我对其他测试用例有太多递归调用

I'm surprised that it failed on recursive calls before it failed on taking too long to come up with an answer.我很惊讶它在递归调用中失败了,然后才花了太长时间才给出答案。 The recursion depth is the same as k , so k would have had to reach 1000 for default Python to choke on it.递归深度与k相同,因此k必须达到 1000 才能使默认 Python 窒息。 However, your code takes 4 minutes to solve what appears to be a simple example:但是,您的代码需要 4 分钟才能解决看似简单的示例:

print(stringReduction(8, "dermosynovitis"))

The amount of time is a function of k and string length.时间量是k和字符串长度的function。 The problem as I see it, recursively, is this code:递归地,我看到的问题是这段代码:

for i in range(len(s)):
    new_str = s[:i]+s[i+1:]
    strings = allPossibleCombinations(k-1, new_str, strings, depth + 1)

Once we've removed the first character say, and done all the combinations without it, there's nothing stopping the recursive call that drops out the second character from again removing the first character and trying all the combinations.一旦我们删除了第一个字符,并在没有它的情况下完成了所有组合,就没有什么可以阻止递归调用从再次删除第一个字符并尝试所有组合中删除第二个字符。 We're (re)testing too many strings!我们正在(重新)测试太多的字符串!

The basic problem is that you need to prune (ie avoid) strings as you test, rather than generate all possibilties and test them.基本问题是您需要在测试时修剪(即避免)字符串,而不是生成所有可能性并测试它们。 If a candidate's first letter is less than that of the best string you've seen so far, no manipulation of the remaining characters in that candidate is going to improve it.如果候选人的第一个字母小于您迄今为止看到的最佳字符串的首字母,则对该候选人中剩余字符的任何操作都不会改善它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM