简体   繁体   English

如何在列表中找到第二大数字?

[英]How to find second largest number in a list?

So I have to find the second largest number from list.所以我必须从列表中找到第二大数字。 I am doing it through simple loops.我是通过简单的循环来做的。

My approach is to divide a list into two parts and then find the largest number into two parts and then compare two numbers.我的方法是将一个列表分成两部分,然后将最大的数分成两部分,然后比较两个数字。 I will choose the smaller number from two of them.我将从其中两个中选择较小的数字。 I can not use ready functions or different approaches.我不能使用现成的功能或不同的方法。

Basically, this is my code.基本上,这是我的代码。 But it does not run correctly但它不能正确运行

#!/usr/local/bin/python2.7

alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
largest=alist[0]
h=len(alist)/2 
m=len(alist)-h

print(alist)

for i in alist:
    if alist[h]>largest:
      largest=alist[h]
      i=i+1
print(largest)

O(n^2) algorithm: O(n^2) 算法:

In [79]: alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]

In [80]: max(n for n in alist if n!=max(alist))
Out[80]: 100

O(n) algorithm: O(n) 算法:

In [81]: alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]

In [82]: M = max(alist)

In [83]: max(n for n in alist if n!=M)
Out[83]: 100

You don't have to sort the input, and this solution runs in O(n).您不必对输入进行排序,并且此解决方案以 O(n) 运行。 Since your question says you cannot use builtin functions, you can use this由于你的问题说你不能使用内置函数,你可以使用这个

alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
largest, larger = alist[0], alist[0]

for num in alist:
    if num > largest:
        largest, larger = num, largest
    elif num > larger:
        larger = num
print larger

Output输出

100

Keep track of the largest number and the second largest number ( larger variable stores that in the code).跟踪最大的数字和第二大的数字( larger变量将其存储在代码中)。 If the current number is greater than the largest , current number becomes the largest , largest becomes just larger .如果当前数字大于largest ,则当前数字变为largestlargest变为larger

largest, larger = num, largest is a shortcut for largest, larger = num, largest是一个快捷方式

temp = largest
largest = num
larger = temp

Edit: As per OP's request in the comments,编辑:根据 OP 在评论中的要求,

def findLarge(myList):
    largest, larger = myList[0], myList[0]
    for num in myList:
        if num > largest:
            largest, larger = num, largest
        elif num > larger:
            larger = num
    return largest, larger

alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]

firstLargest, firstLarger  = findLarge(alist[:len(alist)//2])
secondLargest, secondLarger = findLarge(alist[len(alist)//2:])

print sorted((firstLarger, firstLargest, secondLarger, secondLargest))[-2]

If you want an approach that consist in dividing the list, the nearest thing I can think in, is a MergeSort, it works dividing the list in 2, but it sorts a list.如果你想要一种包括划分列表的方法,我能想到的最接近的事情是 MergeSort,它可以将列表分成 2,但它对列表进行排序 Then you can take the last 2 elements.然后你可以取最后 2 个元素。

alist = [1, 7, 3, 2, 8, 5, 6, 4]

def find_2_largest(alist):
    sorted_list = mergesort(alist)
    return (sorted_list[-2], sorted_list[-1])    

def merge(left, right):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result += left[i:]
    result += right[j:]
    return result

def mergesort(alist):
    if len(alist) < 2:
        return alist
    middle = len(alist) / 2
    left = mergesort(alist[:middle])
    right = mergesort(alist[middle:])
    return merge(left, right)

print find_2_largest(alist)

O(n) solution O(n) 解决方案

alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
m = alist[:2] #m will hold 2 values, fill it with the first two values of alist
for num in alist:
    m = sorted(m + [num],reverse=True)[:2] #appends num to m and sorts it, takes only top 2
m[1] #the second highest element.

EDIT: changed to work with negative numbers.编辑:改为使用负数。 Basic description as follows基本说明如下

First I set m to be the first two elements of alist.首先,我将 m 设置为 alist 的前两个元素。 As I iterate through alist I will be adding one value to the end of m, then sorting the three elements and throwing away the smallest one.当我遍历 alist 时,我将在 m 的末尾添加一个值,然后对三个元素进行排序并丢弃最小的一个。 This ensures that at the end m will contain the top two largest elements.这确保最后 m 将包含前两个最大元素。

Try this:试试这个:

alist=[10, 0,3,10,90,5,-2,4,18,45,707, 100,1,-266,706, 1]
largest = alist[0]
second_largest = alist[0]
for i in range(len(alist)):
    if alist[i] > second_largest:
        second_largest = alist[i]
    if alist[i] > largest:
        tmp = second_largest
        second_largest = largest
        largest = tmp      

print(largest, second_largest)

Without giving away code, I will give you my approach to solving this problem.在不提供代码的情况下,我将向您提供我解决此问题的方法。

1.) Take your list, and sort it from least to greatest. 1.) 拿出你的清单,从最小到最大排序。 There is a python function to handle this有一个 python 函数来处理这个

2.) Split your list into two sections 2.) 将您的列表分成两部分

3.) Compare the two sections, take the half with the largest numbers, repeat #2 3.) 比较两部分,取最大数字的一半,重复#2

4.) When either half contains only two numbers, take the first number from that list 4.) 当任一半只包含两个数字时,从该列表中取出第一个数字

The challenge is you will have to decide what to do if the list cannot be evenly split.挑战在于,如果列表不能平均分配,您将不得不决定该怎么做。 Obviously, in the real world, you would sort the list and return the second from last value, but if you must do it by performing a binary split, this is how I would do it :)显然,在现实世界中,您将对列表进行排序并从最后一个值中返回第二个值,但是如果您必须通过执行二进制拆分来执行此操作,那么我将这样做:)

Second largest number in the list:列表中第二大的数字

alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
second_highest_number = sorted(list(set(alist)))[-2]

If you only want the 2nd largest element in the list (in cases where the highest value may occur twice ), just skip the set() and list() call.如果您只想要列表中的第二大元素(在最高值可能出现两次的情况下),只需跳过 set() 和 list() 调用。

alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
second_highest_number = sorted(alist)[-2]
biggest = None
second_biggest = None

biggest = num_list[0]
if num_list[1] > biggest:
   second_biggest = num_list[1]
else:
   second_biggest = biggest
   biggest = num_list [1]

for n in num_list [2:]:
    if n >= biggest:
        biggest, second_biggest = n, biggest
    elif n >= second_biggest:
        second_biggest = n

print second_biggest

I'm amazed that most answers (except by Christian) didn't try to answer OP's real question of finding the solution using divide-and-conquer approach.我很惊讶大多数答案(Christian 除外)并没有试图回答 OP 使用分而治之的方法找到解决方案的真正问题。

This question is almost identical to this question: Finding the second smallest number from the given list using divide-and-conquer , but it tries to find the least instead of the largest.这个问题几乎与这个问题相同: 使用分而治之从给定列表中找到第二小的数字,但它试图找到最小的而不是最大的。

For which this is my answer :这是我的答案

def two_min(arr):
    n = len(arr)
    if n==2:
        if arr[0]<arr[1]:                   # Line 1
            return (arr[0], arr[1])
        else:
            return (arr[1], arr[0])
    (least_left, sec_least_left) = two_min(arr[0:n/2]) # Take the two minimum from the first half
    (least_right, sec_least_right) = two_min(arr[n/2:]) # Take the two minimum from the second half
    if least_left < least_right:            # Line 2
        least = least_left
        if least_right < sec_least_left:    # Line 3
            return (least, least_right)
        else:
            return (least, sec_least_left)
    else:
        least = least_right
        if least_left < sec_least_right:    # Line 4
            return (least, least_left)
        else:
            return (least, sec_least_right)

You can try to understand the code and change it to take the two largest.可以试着理解代码,改成取两个最大的。 Basically you divide the array into two parts, then return the two largest numbers from the two parts.基本上,您将数组分成两部分,然后从两部分返回两个最大的数字。 Then you compare the four numbers from the two parts, take the largest two, return.然后比较两部分的四个数字,取最大的两个,返回。

This code has a bonus also for limiting the number of comparisons to 3n/2 - 2 .此代码还有一个好处是将比较次数限制为3n/2 - 2

alist = [-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
largest = 0
second_largest = 0
for large in alist:
  if second_largest < large:
    second_largest = large

  if largest < large:
    temp = second_largest
    second_largest = largest
    largest = temp

print "First Highest:- %s" %largest
print "Second Highest:- %s" %second_largest
alist=[10, 0,3,10,90,5,-2,4,18,45,707, 100,1,-266,706, 1]
print(max(alist))
second_largest=alist[0]
for i in range(len(alist)):
    if (alist[i]>second_largest and alist[i]!=max(alist)):
        second_largest=alist[i]
print(second_largest)
 list1=[1,10,2,3,5,7,1,-32,90,99,99]
 max=0
 secmax=0
 for i in list1:
    if i>max:
       max=i
 for i in list1:
    if i>secmax and max!=i:
      secmax=i
 print(secmax)
alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
sorted_list = sorted(set(alist))
sorted_list.pop()
print(max(sorted_list))

Here is my program, irrespective of complexity这是我的程序,无论复杂性如何

if __name__ == '__main__':
    alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
    alist1 = [ ]
    [alist1.append(x) for x in alist if x not in alist1]
    alist1.sort()
    print alist1[-2]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM