当前位置: 首页 > 面试题库 >

获取线性时间列表中的第二大数字

敖和韵
2023-03-14
问题内容

我正在学习Python,而处理列表的简单方法是一种优势。有时是这样,但请看以下内容:

>>> numbers = [20,67,3,2.6,7,74,2.8,90.8,52.8,4,3,2,5,7]
>>> numbers.remove(max(numbers))
>>> max(numbers)
74

从列表中获取第二大数字的一种非常简单,快速的方法。除了简单的列表处理之外,还可以编写一个遍历列表两次的程序,以找到最大的程序,然后找到第二大的程序。这也是破坏性的-
如果我想保留原始数据,则需要两个数据副本。我们需要:

>>> numbers = [20,67,3,2.6,7,74,2.8,90.8,52.8,4,3,2,5,7]
>>> if numbers[0]>numbers[1]):
...    m, m2 = numbers[0], numbers[1]
... else:
...    m, m2 = numbers[1], numbers[0]
...
>>> for x in numbers[2:]:
...    if x>m2:
...       if x>m:
...          m2, m = m, x
...       else:
...          m2 = x
...
>>> m2
74

该列表仅运行一次,但并不像以前的解决方案那样简洁明了。

那么:在这种情况下,有没有办法让两者兼而有之?第一个版本的清晰度很高,但是第二个版本是否单次运行?


问题答案:

由于@OscarLopez和我对第二大含义是什么有不同的看法,因此我将根据自己的解释并按照发问者提供的第一种算法发布代码。

def second_largest(numbers):
    count = 0
    m1 = m2 = float('-inf')
    for x in numbers:
        count += 1
        if x > m2:
            if x >= m1:
                m1, m2 = x, m1            
            else:
                m2 = x
    return m2 if count >= 2 else None

(注意:此处使用负无穷大,而不是None因为None在Python 2和3中具有不同的排序行为-请参阅Python-
查找第二个最小的数字
;检查其中的元素数numbers可确保当实际的负无穷大时不会返回答案是不确定的。)

如果最大值多次出现,那么它可能也是第二大最大值。关于这种方法的另一件事是,如果元素少于两个,则它可以正常工作;那么没有第二大的。

运行相同的测试:

second_largest([20,67,3,2.6,7,74,2.8,90.8,52.8,4,3,2,5,7])
=> 74
second_largest([1,1,1,1,1,2])
=> 1
second_largest([2,2,2,2,2,1])
=> 2
second_largest([10,7,10])
=> 10
second_largest([1,1,1,1,1,1])
=> 1
second_largest([1])
=> None
second_largest([])
=> None

更新资料

我对条件进行了重组,以大大提高性能。在我对随机数的测试中几乎达到了100%。原因是在原始版本中,elif总是在下一个数字不是列表中最大的可能情况下对进行评估。换句话说,对于列表中的几乎每个数字,都进行了两次比较,而一次比较就足够了–如果该数字不大于第二大数字,那么它也不大于第二大数字。



 类似资料:
  • 问题内容: 已关闭 。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗? 更新问题,使其仅通过编辑此帖子来关注一个问题。 7个月前关闭。 我有这样定义的员工和薪水表: 我可以使用什么查询来获得该表中第二高的薪水? 问题答案: 这是关系的原因。 编辑: 我接受了Manoj的第二篇文章,对其进行了调整,并使它更具可读性。对我来说 n-1 不直观;但是,使用我想要的值是2 = 2nd,3 =

  • 问题内容: 通常,一些答案提到给定的解决方案是 线性的 ,或者另一个是 二次的 。 如何发挥作用/识别什么? 有人能为像我这样仍然不认识的人解释这种最简单的方法吗? 问题答案: 当所需时间随所涉及元素的数量线性增加时,该方法是线性的。例如,用于打印数组元素的for循环大致是线性的: 因为如果我们打印range(100)而不是range(10),则运行它所需的时间要长10倍。您会经常看到写为O(N)

  • 问题内容: 当存在时,是否有可能获得全部列表?是否为此准备了电话,还是我必须编写一个foreach循环,如: 问题答案: Java 8及更高版本: 如果需要确保得到结果,则必须将最后一行更改为: Java 7及以下版本: Java 8之前的标准集合API不支持这种转换。您必须编写一个循环(或将其包装在您自己的“地图”函数中),除非您使用一些更高级的集合API /扩展。 (您的Java代码段中的行正

  • 问题内容: 我有一个非常简单的问题-我想-但似乎我无法解决这个问题。我是Python和Pandas的初学者。我在论坛上进行了搜索,但没有得到符合我需要的(最新)答案。 我有一个这样的数据框: 这使: 我的问题很简单:我想添加一列,以给出 每一行 第二个 最大值的列名。 我编写了一个简单的函数,该函数返回每一行的第二个最大值 这使: 但是我找不到如何在“值”列中显示列名,而不是值…我正在考虑布尔索引

  • 问题内容: 因此,我有一个包含几个列表的列表,这些列表都首先包含三个字符串,然后是一个浮点数,例如: 如何制作一个返回最大值的函数(此处为9.1931)?我试过了 但这只是给我一个清单。 编辑:此外,以任何方式我可以获取值来自何处的索引?喜欢,来自哪个子列表? 问题答案: 循环浏览外部列表,然后选择每个子列表的最后一个元素: 最好将所有与函数相关的变量保留在范围内(将列表作为参数传递,并且不要通过

  • 问题内容: 我有一个这样的清单: 如果仅使用该方法,它将返回答案,如果我试图找到max name ,那将是正确的,但是我试图返回其整数最大的元素。 问题答案: 之所以起作用,是因为 max 函数的 key 参数指定了一个函数,当 max 想要知道用于搜索最大元素的值时,该函数将被调用。 max 将为序列中的每个元素调用该函数。并创建一个接收列表并返回第一个(从零开始计数)元素的小函数。所以 __