【问题标题】:How can I optimize the code current algorithm take O(n+m+k)?如何优化代码当前算法采用 O(n+m+k)?
【发布时间】:2016-06-26 21:52:21
【问题描述】:

我有三个数组,h1, h2, h3

n1, n2,n3 决定数组的长度。

我必须从 1 个或多个数组中删除输入,以便所有数组的最终总和应该相同。

###Inputs
n1,n2, n3 = 5, 3, 4
h1 = 3 2 1 1 1 # 5 elements
h2 = 4 3 2     # 3 elements
h3 = 1 1 4 1   # 4 elements

如果我们在上面的数组中看到

sum of h1 = 8 sum of h2 = 9 sum of h3 = 7 数组开头的deletion should happen。 所以在这里,如果我删除, 3 from h1 (as h1[0]) 4 from h2 (as h2[0]) 1 and 1 from h3 (as h3[0] and h3[1]) 现在所有(Sum of h1 containts, h2 containts, h3 containts) 的总和将变为5。这是我的最终答案。 当输入列表很小时,下面的代码表现良好。但是当输入列表变为n1 = 100000, n2 = 200000, n3 = 300000。此代码需要大量时间来执行。我怎样才能减少时间。

from collections import *
n1,n2,n3 = input().strip().split(' ')
n1,n2,n3 = [int(n1),int(n2),int(n3)]
h1 = [int(h1_temp) for h1_temp in input().strip().split(' ')]
h2 = [int(h2_temp) for h2_temp in input().strip().split(' ')]
h3 = [int(h3_temp) for h3_temp in input().strip().split(' ')]
#print(n1, n2, n3, h1, h2, h3)
h1_tot, h2_tot, h3_tot = sum(h1), sum(h2), sum(h3)
#print(h1_tot, h2_tot, h3_tot)
arr = [h1_tot, h2_tot, h3_tot]
done = False
while len(Counter(arr)) != 1:
    if len(Counter(arr)) == 3:
        if arr.index(min(Counter(arr))) == 0:
            h3.remove(h3[0])
            h2.remove(h2[0])
        elif arr.index(min(Counter(arr))) == 1:
            h3.remove(h3[0])
            h1.remove(h1[0])
        else:
            h1.remove(h1[0])
            h2.remove(h2[0])
    if len(Counter(arr)) == 2:
        index = arr.index(min(arr))
        if arr[0] == arr[1] and  index == 2:
            h1.remove(h1[0])
            h2.remove(h2[0])
        elif arr[1] == arr[2] and index == 0:
            h2.remove(h2[0])
            h3.remove(h3[0])
        elif arr[0] == arr[2] and index == 1:
            h1.remove(h1[0])
            h3.remove(h3[0])
        if arr[0] == arr[1] and (index == 0 or index == 1):
            h3.remove(h3[0])
        elif arr[1] == arr[2] and  (index == 2 or index == 1):
            h1.remove(h1[0])
        elif arr[0] == arr[2] and  (index == 0 or index == 2):
            h2.remove(h2[0])

    h1_tot, h2_tot, h3_tot = sum(h1), sum(h2), sum(h3)

    arr = [h1_tot, h2_tot, h3_tot]



print(arr[0])

【问题讨论】:

    标签: arrays algorithm python-3.x


    【解决方案1】:

    从 Python 列表的开头删除很慢 (O(N)),因为 Python 需要将对所有其他项目的引用复制到新索引(将它们上移一个空格)。相比之下,从列表末尾删除速度很快 (O(1)),因为它只会删除一个引用并调整大小。

    因此,为了提高算法的性能,我建议使用反向列表,以便您首先删除的项目位于最后。您可以在列表理解中使用reversed 函数来反转它们,或者在创建列表后使用list.reverse 方法。完成算法后,您可以通过再次反转将它们恢复到预期的顺序。

    您还需要使用list.popdel some_list[-1] 而不是list.remove,因为后者最终仍然会很慢(因为它需要在列表中搜索要删除的项目)。

    虽然我认为这不会对您的性能造成太大影响,但您也有很多非常重复的代码。当您看到这一点并且变量中包含数字时,这几乎总是表明您可以通过使用可索引数据结构而不是自变量来大大简化代码。以下是我如何使用列表列表(以及它们的总和列表)来解决您的问题:

    lengths = [int(x) for x in input().split()] # this is ignored by the rest of the code
    
    values = [[int(x) for x in reversed(input().split())] for _ in range(3)]  # make a list of
    sums = [sum(v) for v in values]                                           # reversed lists
    
    while not sums[0] == sums[1] == sums[2]: # if there wasn't a fixed number of lists, I'd use
        max_sum = max(sums)                  # something like "if max(sums) == min(sums)"
        for i, (v, s) in enumerate(zip(values, sums)): # this loop over the lists lets us avoid
            if s == max_sum:                           # duplicating our code for each one
                sums[i] -= v.pop(-1) # pop is fast at the end!
    
    for v in values:  # I'm not sure what the desired output is, so I'm just printing the lists.
        v.reverse()   # Could instead use print(*reversed(v)) for formatting like in the input.
        print(v)
    

    【讨论】:

      猜你喜欢
      • 2019-12-23
      • 1970-01-01
      • 2012-04-12
      • 1970-01-01
      • 2022-10-13
      • 2013-02-21
      • 1970-01-01
      • 2021-06-18
      • 2023-03-08
      相关资源
      最近更新 更多