【问题标题】:Can this function be optimized to run in O(n) time using Python?可以使用 Python 优化此函数以在 O(n) 时间内运行吗?
【发布时间】:2020-06-15 13:55:43
【问题描述】:

这是场景。

该函数接受一个包含 n 个项目权重的数组和一个包含 q 个容量的数组。目标是根据容量找出每个箱子可以容纳的物品数量。

我编写了以下函数,但我遇到的问题是它在非常大的输入值上超时。看看下面:

def noItems(weights, capacities):
    number_of_items = 0
    result = []
    weight_sums = [sum(weights[0:w:1]) for w in range(1, len(weights) + 1)]

    for i in range(0, len(capacities)):
        for j in range(0, len(weight_sums)):
            if weight_sums[j] <= capacities[i]:              
                number_of_items = number_of_items + 1

        result.append(number_of_items)

        number_of_items = 0

    return(result)

更新:示例输入和输出

输入权重:[2, 3, 5, 8, 1, 4, 7]

输入容量:[10, 20, 18, 1, 40, 4]

输入约束: 权重[i] > 1 且 1 和

输出:[3, 5, 4, 0, 7, 1]

如何优化此函数以获得更快的运行时间,从而不会在非常大的输入时超时?

【问题讨论】:

  • 我投票结束这个问题,因为它属于codereview.stackexchange.com
  • “最佳解决方案”和“更快的运行时间”是不同的东西
  • 给出一小组重量和容量,以及想要的结果。
  • @RickJames 进行了更新
  • @mangusta 我的解决方案是在非常大的输入上超时。所以我想看看可以做些什么来防止这种情况发生。

标签: python python-3.x algorithm optimization time-complexity


【解决方案1】:

你可以在O(nlogn)时间内使用累积权重列表的二分搜索解决这个问题

from bisect import bisect_right

def noItems(weights, capacities):
    result = []

    # or you can use itertools.accumulate():
    weight_sums = [0] * (len(weights))
    weight_sums[0] = weights[0]
    for i in range(1, len(weights)):
        weight_sums[i] = weight_sums[i-1] + weights[i]

    for x in capacities:
        number_of_items = bisect_right(weight_sums, x)
        result.append(number_of_items)
    return(result)

we =  [2, 3, 5, 8, 1, 4, 7]
ca = [10, 20, 18, 1, 40, 4]
print(noItems(we, ca))
[3, 5, 4, 0, 7, 1]

O(n) 只能用于先前排序的容量。

【讨论】:

  • 感谢您的帮助,但该函数在大输入时仍会超时。
  • 因为二次累积和(我没有注意到这个事实)
  • 累计金额有问题吗?怎么样?
  • 用线性累积和编辑
  • 不,在双 for 循环中计算总和和搜索都是二次的
猜你喜欢
  • 2016-01-27
  • 2021-10-27
  • 2022-01-16
  • 1970-01-01
  • 2011-08-27
  • 2012-06-27
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
相关资源
最近更新 更多