如何找到列表中两个元素的最大乘积?

Posted

技术标签:

【中文标题】如何找到列表中两个元素的最大乘积?【英文标题】:How to find the maximum product of two elements in a list? 【发布时间】:2016-09-05 11:40:39 【问题描述】:

为了好玩,我在hackerrank比赛中尝试了一个问题,结果出现了这个问题。 我为此使用了 itertools,这是代码:

import itertools

l = []

for _ in range(int(input())):
    l.append(int(input()))


max = l[0] * l[len(l)-1]

for a,b in itertools.combinations(l,2):
    if max < (a*b):
        max = (a*b)
print(max)

他们还有其他有效的方法吗?因为我在一些我无法访问的测试用例上遇到超时错误(作为一个小竞赛)。

【问题讨论】:

预计算 a*b 当最大值不是最大值时,您将保存一些指令。 @Jean-FrançoisFabre 没听清楚,能否详细说明? 你不只需要找到两个最大的单个元素并将它们相乘吗? (如果您允许负数,还有两个最低的负数) @khelwood 我考虑过,但在问题中明确写出不要依赖于“请记住,答案并不总是两个最大数字的乘积”。但我的主要问题是为什么会超时! @Maverick 您也可以通过检查负数来记住这一点。否则,您正在为 O(n) 问题编写 O(n^2) 解决方案。 【参考方案1】:

遍历列表并找到以下内容:

最大正数(a)

第二大正数(b)

最大负数(c)

第二大负数(d)

现在,您将能够计算出乘法的最大值,a*bc*d

【讨论】:

很好的逻辑,我选择了有 heapq 解决方案的答案。谢谢你的回答。【参考方案2】:

只需对列表进行排序,选择列表中最后2项和列表前2项中最大的产品:

from operator import mul

numbers = [10, 20, 1, -11, 100, -12]
l = sorted(numbers)    # or sort in place with numbers.sort() if you don't mind mutating the list
max_product = max(mul(*l[:2]), mul(*l[-2:]))

由于排序,这是一个 O(n log n) 解决方案。其他人提出了一个heapq 解决方案,我发现它比几千个随机整数更长的列表更快。

【讨论】:

感谢您的回答,但是 heapq 适用于某些测试用例,因此必须对其进行标记。我也喜欢你的解决方案,它更简单。 @Maverick:没问题。它们基本上是等价的,但在某些情况下 heapq 稍快。【参考方案3】:

这是一个遵循@User_Targaryen 逻辑的实现。 heapq 返回列表中最大的 2 个和最小的 2 个数字,mul operator 返回这 2 对数字的乘积,max 返回这两个乘积中最大的。

>>> import heapq
>>> from operator import mul
>>> l = [2,40,600,3,-89,-899]
>>> max(mul(*heapq.nsmallest(2,l)),mul(*heapq.nlargest(2,l)))
80011
# -899*-89 = 80011

【讨论】:

这是一个很好的,没有超时,但仍然在一个测试用例上失败,不知道为什么。这是链接如果有人想尝试hackerrank.com/contests/arraysloops/challenges/arraysloops-4 @Maverick 在阅读此***.com/questions/2104782/… 后,我已经稍微编辑了我的答案以使用mul 而不是lambda 语法 你不需要使用reduce,尝试元组解包:max(mul(*heapq.nsmallest(2, l)), mul(*heapq.nlargest(2, l)))。对于长列表,这个 heapq 解决方案比我基于排序的解决方案更快。

以上是关于如何找到列表中两个元素的最大乘积?的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1460. 通过翻转子数组使两个数组相等 / 658. 找到 K 个最接近的元素 / 1464. 数组中两元素的最大乘积

LeetCode 1460. 通过翻转子数组使两个数组相等 / 658. 找到 K 个最接近的元素 / 1464. 数组中两元素的最大乘积

如何将列表中的两个最大元素相加?

数组628. 三个数的最大乘积

漫画:去掉一个数,如何让剩余的数乘积最大?

华为OD机试 - 乘积最大值(Python)