如何找到列表中两个元素的最大乘积?
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*b
或 c*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. 数组中两元素的最大乘积