python MaxProductOfThree如何提高性能

uxh89sit  于 2023-01-16  发布在  Python
关注(0)|答案(5)|浏览(171)

三个课程的最大乘积:https://app.codility.com/programmers/lessons/6-sorting/max_product_of_three/
为了解决这一课,我编写了这个函数,如下所示;

import itertools

def solution(A):
    combs=[]

    for pivot_element in A:
        to_comb=A[A.index(pivot_element):]

        for comb in itertools.combinations(to_comb, 3):
           mul_comb= comb[0] * comb[1] * comb[2]
           combs.append(mul_comb) 

    return max(combs)

我的结果是,

result_of_algorithm={
                    "correctness":100,
                    "performance":0,
                    "overall":44,
                    "time complexity": "O(N^3)"
                    }

我怎样才能把它的性能提高到O(n)时间复杂度?

nbewdwxp

nbewdwxp1#

O(n)版本的schwobaseggl解,也得到了100%:

from heapq import nsmallest, nlargest

def solution(A):
    a, b = nsmallest(2, A)
    z, y, x = nlargest(3, A)
    return max(a*b*z, x*y*z)

具有最大允许事例的基准(-1000到1000之间的100,000个值):

204 ms  206 ms  208 ms  210 ms  212 ms  sort
 76 ms   77 ms   78 ms   79 ms   81 ms  heapq
134 ms  135 ms  135 ms  135 ms  136 ms  oneloop
144 ms  146 ms  147 ms  149 ms  151 ms  twoloops
  3 ms    3 ms    3 ms    3 ms    4 ms  baseline

基准测试代码(在线试用!):

from timeit import repeat
from random import choices
from heapq import nsmallest, nlargest
import sys

def sort(A):
    A.sort()
    p1 = A[0] * A[1] * A[-1]
    p2 = A[-3] * A[-2] * A[-1]
    return max(p1, p2)

def heapq(A):
    a, b = nsmallest(2, A)
    z, y, x = nlargest(3, A)
    return max(a*b*z, x*y*z)

def oneloop(A):
    min1 = sys.maxsize * 2
    min2 = sys.maxsize * 2
    max1 = -sys.maxsize * 2
    max2 = -sys.maxsize * 2
    max3 = -sys.maxsize * 2
    for Ai in A:
        if Ai <= min1:
            min2 = min1
            min1 = Ai
        elif Ai <= min2:
            min2 = Ai
        if Ai >= max1:
            max3 = max2
            max2 = max1
            max1 = Ai
        elif Ai >= max2:
            max3 = max2
            max2 = Ai
        elif Ai >= max3:
            max3 = Ai
    return max([min1 * min2 * max1, max1 * max2 * max3])

def twoloops(A):
    min1 = sys.maxsize * 2
    min2 = sys.maxsize * 2
    max1 = -sys.maxsize * 2
    max2 = -sys.maxsize * 2
    max3 = -sys.maxsize * 2
    for Ai in A:
        if Ai <= min1:
            min2 = min1
            min1 = Ai
        elif Ai <= min2:
            min2 = Ai
    for Ai in A:
        if Ai >= max1:
            max3 = max2
            max2 = max1
            max1 = Ai
        elif Ai >= max2:
            max3 = max2
            max2 = Ai
        elif Ai >= max3:
            max3 = Ai
    return max([min1 * min2 * max1, max1 * max2 * max3])

def baseline(A):
    pass

funcs = sort, heapq, oneloop, twoloops, baseline

for _ in range(3):
    A = choices(range(-1000, 1001), k=100_000)
    for func in funcs:
        times = sorted(repeat(lambda: func(A[:]), number=10))
        print(*('%3d ms ' % (t * 1e3) for t in times), func.__name__)
    print()
dgjrabp2

dgjrabp22#

简单地说,你可以在对数线性时间内完成:

def solution(A):
    A.sort()
    p1 = A[0] * A[1] * A[-1]
    p2 = A[-3] * A[-2] * A[-1]
    return max(p1, p2)

排序允许你只尝试排序顺序两端的数字。这两个选项说明了包括负数的可能性。它在正确性和性能上都达到了100%。

oyt4ldly

oyt4ldly3#

从这个来源我得到了一个非常简单的解决方案:https://youtu.be/qr3i9cXAjbc
这个算法和@schwobaseggl的答案中的算法是一样的,就像下面一样。在性能和正确性上都是100分。

def solution(A):
    A.sort()
    N=len(A)

    P1 = A[N-1] * A[0] * A[1]
    P2 = A[N-1] * A[N-2] * A[N-3]

    return max(P1,P2)
92dk7w1h

92dk7w1h4#

该想法描述如下:https://afteracademy.com/blog/maximum-product-of-three-numbers
只有两个可能的选项:
1.你需要三个最大的数字(如果所有的数字都是正数,情况显然如此)
1.你需要最大的数和两个最小的数,只有当两个最小的数为负数,并且它们的乘积大于第二大数和第三大数的乘积时,才能得到最大的数和两个最小数的乘积,显然,两个最小数的乘积是正数,你需要把它乘以最大数。
你需要检查这两种情况,然后返回更大的值,我把链接中的代码改编成Python,它的时间复杂度为O(n),因为我们只迭代列表中的一个:

# solution.py
import sys

def solution(A):
    min1 = sys.maxsize * 2
    min2 = sys.maxsize * 2
    max1 = -sys.maxsize * 2
    max2 = -sys.maxsize * 2
    max3 = -sys.maxsize * 2

    for Ai in A:
        if Ai <= min1:
            min2 = min1
            min1 = Ai
        elif Ai <= min2:
            min2 = Ai
        if Ai >= max1:
            max3 = max2
            max2 = max1
            max1 = Ai
        elif Ai >= max2:
            max3 = max2
            max2 = Ai
        elif Ai >= max3:
            max3 = Ai
    return max([min1 * min2 * max1, max1 * max2 * max3])

例如,print(solution([-11, -10, 1, 2, 3, 4, 5, 6, 7, 8, 9]))会给出990-11 * -10 * 9

pzfprimi

pzfprimi5#

def maxproduct(a):
    i = 0
    max_three = [float('-inf')]
    idx = []
    while i < len(a) - 1:
        temp = max(a[i:i+2])
        if temp > max_three[-1]:
            max_three.append(temp)
        i +=1
        
    return [a.index(e) for e in (max_three[-3:])]
    
maxproduct(a)

相关问题