如何将列表中的两个最大元素相加?
Posted
技术标签:
【中文标题】如何将列表中的两个最大元素相加?【英文标题】:How to sum the two largests elements in a list? 【发布时间】:2018-07-17 21:35:54 【问题描述】:我有一个这样的列表:
[1, 2, 5, 2, 7, 3, 9, 5...]
有没有一种有效的方法可以在这里找到两个最大元素的总和:
for i in range():
for j in range():
我发现了这个: "最大子数组问题"
但我还没有完全理解它的作用。
【问题讨论】:
所以在这种情况下,结果将是9
+ 7
?
您可以对数组进行排序,使最大的数字在开头,然后将前两个元素相加
是的,但就我而言,我有一个随机列表。我把它作为输入,我尽量避免检查每个元素
@TrueBad0ur 你应该澄清一些非常重要的事情。当最大值发生不止一次时,所需的输出是什么?例如,如果您的列表是[1, 2, 5, 2, 7, 3, 9, 9]
,您想要的答案是9+9
还是9+7
?
【参考方案1】:
sum(sorted([9,8,1,3,4,5,7,0])[-2:])
-
对所有元素进行排序
获取最后两个元素
总结一下
【讨论】:
或sum(sorted([9,8,1,3,4,5,7,0], reverse=True)[0:2])
应该有一个O(N)
解决方案
或者我们可以使用sum(heapq.nlargest(2, your_list))
这是一个线性问题的 n log n 解;不应该被接受。其他人已经给出了线性时间解决方案:读取一次数组,跟踪两个最大的 elt,并将它们添加到末尾。
@Dave 这取决于...就纯性能而言,您是对的,这是次优的。但是,您知道,如果您没有数百万个数字,那么该解决方案与线性解决方案在性能方面的差异将只有几微秒。然而,大的不同之处在于这段代码更具可读性。【参考方案2】:
这是一个线性时间解:
#initialize these to huge negative numbers
largest = -1e10
second_largest = -1e11
l = [9,8,1,3,4,5,7,0]
for item in l:
if item > largest:
second_largest = largest
largest = item
elif item > second_largest:
second_largest = item
print(largest+second_largest)
# 17
【讨论】:
【参考方案3】:这里是线性解:
x = [1, 2, 5, 2, 7, 3, 9, 5]
max1 = -1;
max2 = -1;
for i in range(len(x)):
if x[i] > max1:
max2 = max1
max1 = x[i]
elif x[i] > max2:
max2 = x[i]
print(max1+max2)
如果您的数组仅包含正整数,则考虑将 max1、max2 更改为可能的最低值
【讨论】:
【参考方案4】:另一个 O(n) 解决方案,但更 Pythonic,放弃了一点性能(在列表上迭代 4 次)
l = [1, 2, 5, 2, 7, 3, 9, 5]
# find largest
largest = max(l)
# remove from list
l.remove(largest)
# second largest
largest2 = max(l)
# remove from list
l.remove(largest2)
print(largest+largest2)
>> 16
为了让它更紧凑一点,一行中完全相同的过程:
l = [1, 2, 5, 2, 7, 3, 9, 5]
l.pop(l.index(max(l))) + l.pop(l.index(max(l)))
print(largest+largest2)
>> 16
【讨论】:
你不需要l.remove(largest2)
,但这行得通。
我喜欢这个解决方案。简单高效。如果你不允许使用内置的 max() 和 remove(),你可以对它们进行编码,但我喜欢这个想法的简单性。
此解决方案可能有效或无效,具体取决于您对“最大”的定义。如果最大的数字重复会发生什么?你应该删除它的所有实例,这是另一个 \$O(n)\$ 操作,还是给出largest * 2
作为结果?
并非如此,remove 会删除最大值的第一个匹配项。下一步将找到相同的最大值(不同的索引)并将其删除。如此快速的答案是它将具有与其他解决方案相同的行为(例如排序,获取 [:2])。它将导致最大 * 2【参考方案5】:
如果你不介意使用库,可以使用heapq
的nlargest
:
import heapq
x = [1, 2, 5, 2, 7, 3, 9, 5]
然后
sum(heapq.nlargest(2, x))
会回来
16
pandas 也是一个选项(但只有在您导入它时才使用它,因为它是一个相当重的依赖项):
import pandas as pd
pd.Series(x).nlargest(2).sum()
也返回16
如果您有重复的最大值,您可以使用sets
:
x = [1, 2, 5, 2, 7, 3, 9, 5, 9]
然后
sum(heapq.nlargest(2, x))
会回来
18
作为9 + 9 = 18
和
sum(heapq.nlargest(2, set(x)))
将返回
16
然后计算9 + 7 = 16
。
【讨论】:
【参考方案6】:具有唯一编号
这是最简单的方法
a = [1, 2, 5, 2, 7, 3, 9, 5]
m1 = max(a)
a.pop(a.index(m1))
m2 = max(a)
print(m1 + m2)
输出:16
如果你有更多相等的数字,但你想摆脱它们 - 这样你就可以添加两个最大的不同数字 - 你可以这样做:
a = [1, 2, 5, 2, 7, 3, 9, 5]
a = set(a)
m1 = max(a)
a = list(a)
a.pop(a.index(m1))
m2 = max(a)
print(m1 + m2)
输出:16
如果您想在列表中添加最大的数字,即使它们相同(即 9 和 9),请使用第一个代码示例,它会为您工作。
【讨论】:
以上是关于如何将列表中的两个最大元素相加?的主要内容,如果未能解决你的问题,请参考以下文章
将一个数字与 Python 中列表(或数组)中的每个元素相加