Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查找置换时减少运行时间_Python_Permutation - Fatal编程技术网

Python 查找置换时减少运行时间

Python 查找置换时减少运行时间,python,permutation,Python,Permutation,我正在谷歌的FooBar挑战中寻找乐趣,在谷歌的运行时环境中执行时遇到了一个超过时间限制的错误。我的解决方案在我当地的开发环境中运行良好,而且在我看来运行速度很快 这是我的代码: from itertools import permutations def answer(l): options = [] for r in range(1, len(l) + 1): for p in permutations(l, r=r): n = in

我正在谷歌的FooBar挑战中寻找乐趣,在谷歌的运行时环境中执行时遇到了一个超过时间限制的错误。我的解决方案在我当地的开发环境中运行良好,而且在我看来运行速度很快

这是我的代码:

from itertools import permutations

def answer(l):
    options = []
    for r in range(1, len(l) + 1):
        for p in permutations(l, r=r):
            n = int(''.join(map(str, p)))
            if n % 3 == 0:
                options.append(n)
    numbers = sorted(options, reverse=True)
    return numbers[0]

l = [3, 1, 4, 1, 5, 9]
#l = [3, 1, 4, 1]
print(answer(l))
目标是从传入的数字列表中找到可被3整除的最大数字

两个示例的输出应为:

[3, 1, 4, 1, 5, 9] => 94311
[3, 1, 4, 1] => 4311
根据注释生成从最大到最小(而不是从最小到最大)的排列,然后进行分组,我修改了代码。相反,它在本地环境中工作,但Google运行时表示已超过时间限制:

def answer(l):
    options = []
    l = sorted(l, reverse=True)
    for r in range(len(l) + 1, 1, -1):
        for p in permutations(l, r=r):
            n = int(''.join(map(str, p)))
            if n % 3 == 0:
                return n
    return 0
我是根据排序规则对输入列表进行排序的,也就是说,如果输入被排序,元组将被排序。然后,因为它应该被排序,所以当它第一次找到一个可被3整除的值时,它将是最高的值

正如我所说的,我的代码(两个版本)都有效。但是,我的跑步时间似乎比谷歌预期的要长。如何减少上述代码的运行时间

  • 最高数字的位数最多。因此,对于一个 大小为n的列表,搜索应从n开始并继续到n-1, n-2

  • 可被3整除的数字总是在解中。对于 示例2514可被3整除,因此是32514或35314。因此,您可以减少 搜索不可被3整除的数字

  • 对于不可被3整除的n位数列表(n>=3),您可以 通过删除最多2个数字来获得一个可被3整除的数字。这是因为求和将有余数1或2。如果是1,在最坏的情况下,您可以删除2个数字,剩余部分为2。如果是2,在最坏的情况下,您可以删除2个数字,剩余部分为1

  • 现在算法是:

    您有一个数字列表:

    divisible = [i for i in numbers if i % 3 == 0]
    candidate_list = [i for i in numbers if i % 3 != 0]
    
    如果候选列表的总和可以被3整除,那么你就得到了答案。如果不是,请查看其余部分:

    remainder = sum(candidate_list) % 3
    
    如果余数为1,我们将在候选列表中搜索1、4或7。如果是2,则数字将是2、5和8。如果我们找到一个数字,我们将把它从列表中删除,剩下的数字之和将被三整除

    if remainder!=0:
        for i in range(3):
            if (remainder + i*3) in candidate_list:
                candidate_list.remove(remainder + i*3)
                return candidate_list
    
    这将从最小的数字开始搜索,并在找到数字时中断循环。如果不是,我们将搜索两个数字,而不是1

    counter = 0
    for candidate in candidate_list:
        if candidate % 3 + remainder == 3:
            candidate_list.remove(candidate)
            counter += 1
            if counter > 1:
                return candidate_list
    
    总的来说,您将有如下内容:

    numbers = [3, 1, 4, 1, 5, 9, 0, 2, 4, 7, 9, 1, 3]
    divisible = [i for i in numbers if i % 3 == 0]
    
    def search(numbers):
        candidate_list = sorted([i for i in numbers if i % 3 != 0])
        remainder = sum(candidate_list) % 3
        if remainder!=0:
            for i in range(3):
                if (remainder + i*3) in candidate_list:
                    candidate_list.remove(remainder + i*3)
                    return candidate_list
            counter = 0
            for candidate in candidate_list:
                if candidate % 3 + remainder == 3:
                    candidate_list.remove(candidate)
                    counter += 1
                    if counter > 1:
                        return candidate_list
        else:
            return candidate_list
    
    candidate_list = search(numbers)
    fin = int(''.join(map(str, sorted(divisible + candidate_list, reverse=True))))
    
  • 最高数字的位数最多。因此,对于一个 大小为n的列表,搜索应从n开始并继续到n-1, n-2

  • 可被3整除的数字总是在解中。对于 示例2514可被3整除,因此是32514或35314。因此,您可以减少 搜索不可被3整除的数字

  • 对于不可被3整除的n位数列表(n>=3),您可以 通过删除最多2个数字来获得一个可被3整除的数字。这是因为求和将有余数1或2。如果是1,在最坏的情况下,您可以删除2个数字,剩余部分为2。如果是2,在最坏的情况下,您可以删除2个数字,剩余部分为1

  • 现在算法是:

    您有一个数字列表:

    divisible = [i for i in numbers if i % 3 == 0]
    candidate_list = [i for i in numbers if i % 3 != 0]
    
    如果候选列表的总和可以被3整除,那么你就得到了答案。如果不是,请查看其余部分:

    remainder = sum(candidate_list) % 3
    
    如果余数为1,我们将在候选列表中搜索1、4或7。如果是2,则数字将是2、5和8。如果我们找到一个数字,我们将把它从列表中删除,剩下的数字之和将被三整除

    if remainder!=0:
        for i in range(3):
            if (remainder + i*3) in candidate_list:
                candidate_list.remove(remainder + i*3)
                return candidate_list
    
    这将从最小的数字开始搜索,并在找到数字时中断循环。如果不是,我们将搜索两个数字,而不是1

    counter = 0
    for candidate in candidate_list:
        if candidate % 3 + remainder == 3:
            candidate_list.remove(candidate)
            counter += 1
            if counter > 1:
                return candidate_list
    
    总的来说,您将有如下内容:

    numbers = [3, 1, 4, 1, 5, 9, 0, 2, 4, 7, 9, 1, 3]
    divisible = [i for i in numbers if i % 3 == 0]
    
    def search(numbers):
        candidate_list = sorted([i for i in numbers if i % 3 != 0])
        remainder = sum(candidate_list) % 3
        if remainder!=0:
            for i in range(3):
                if (remainder + i*3) in candidate_list:
                    candidate_list.remove(remainder + i*3)
                    return candidate_list
            counter = 0
            for candidate in candidate_list:
                if candidate % 3 + remainder == 3:
                    candidate_list.remove(candidate)
                    counter += 1
                    if counter > 1:
                        return candidate_list
        else:
            return candidate_list
    
    candidate_list = search(numbers)
    fin = int(''.join(map(str, sorted(divisible + candidate_list, reverse=True))))
    

    尝试在这里发布改进工作代码:似乎您正在生成所有排列。相反,你可以试着从最大到最小生成,当你找到一个解决方案时,它将是最大的。试着在这里发布改进工作代码:看起来你正在生成所有的排列。相反,您可以尝试从最大到最小生成,并在找到解决方案时进行分解,因为它将是最大的解决方案。