How to find second largest number in a list?

前端 未结 14 1884
遇见更好的自我
遇见更好的自我 2020-12-06 15:38

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 n

相关标签:
14条回答
  • 2020-12-06 15:42

    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. Then you can take the last 2 elements.

    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)
    
    0 讨论(0)
  • 2020-12-06 15:42
    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
    
    0 讨论(0)
  • 2020-12-06 15:45

    You don't have to sort the input, and this solution runs in 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). If the current number is greater than the largest, current number becomes the largest, largest becomes just larger.

    largest, larger = num, largest is a shortcut for

    temp = largest
    largest = num
    larger = temp
    

    Edit: As per OP's request in the comments,

    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]
    
    0 讨论(0)
  • 2020-12-06 15:49

    O(n^2) algorithm:

    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:

    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
    
    0 讨论(0)
  • 2020-12-06 15:50

    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.

    alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
    second_highest_number = sorted(alist)[-2]
    
    0 讨论(0)
  • 2020-12-06 15:53

    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.

    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.

    0 讨论(0)
提交回复
热议问题