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

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】:

如果你不介意使用库,可以使用heapqnlargest

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 中列表(或数组)中的每个元素相加

python 怎么将列表的值相加1?

matlab如何将两个矩阵的指定元素相加放入一个空矩阵中

如何将从特定索引开始的列表与python中的另一个索引相加

使用两个嵌套的 for 循环和 str() 函数将列表中的偶数相加

Array Partition I