【问题标题】:Finding the second largest element in a list (for duplicate elements)查找列表中的第二大元素(对于重复元素)
【发布时间】:2019-04-14 15:04:24
【问题描述】:

我正在尝试查找数组中的第二大元素。我的代码适用于大多数输入,但对于某些输入,它失败了。 另外,如果我输入[6, 6, 6, 5],程序应该输出5作为第二大而不是6。

对于[6,6,6,6,6,6,6,6,6,5],它打印的是 6 而不是 5。 对于重复元素,它会给出错误的结果。

# Given the participants' score sheet for your University Sports Day, you are required to find the runner-up score.
# You are given scores. Store them in a list and find the score of the runner-up.


if __name__ == '__main__':
    n = int(input("Enter the total numbers: "))
    arr = list(map(int, input("Enter the numbers: ").split()))
    if arr[0] >= arr[1]:
        first_max = arr[0]
        second_max = arr[1]
    else:
        first_max = arr[1]
        second_max = arr[0]
    for i in range(2, n):
        if arr[i] > first_max:
            second_max = first_max
            first_max = arr[i]
        elif arr[i] > second_max and arr[i] != first_max:
            second_max = arr[i]

    print(second_max)

请有人解释一下它背后的逻辑。

【问题讨论】:

  • 为什么不sorted(set(arr))[-2]
  • 那行得通。但我想知道一般逻辑,而不是特定语言的解决方案。
  • 我主要是要求重复元素。
  • 在源代码中包含一个问题陈述——下一次,使用docstring。如果你为业务逻辑定义了一个函数,你也可以在那里添加一个。

标签: python algorithm logic


【解决方案1】:

问题在于你在这里写的第一个和第二个最大值的初始化

    if arr[0] >= arr[1]:
    first_max = arr[0]
    second_max = arr[1]
else:
    first_max = arr[1]
    second_max = arr[0]

[6,6,6,6,6,6,6,6,6,5] 的情况下,first_max 和 second_max 都等于 6,当给定 5 时不能更改它们,因为第二个最大值仍然大于 5。

解决方案是编辑这部分代码

之前

elif arr[i] > second_max and arr[i] != first_max: second_max = arr[i]

之后

elif first_max == second_max or (arr[i] > second_max and arr[i] != first_max: second_max = arr[i])

【讨论】:

  • 那么解决方案是什么?算法错了吗?
  • 我已经用一个可能的解决方案更新了我的答案,该解决方案只需要根据您的代码进行最少的更改
【解决方案2】:

当前 2 个元素为 6 时,您的问题就开始了。所以第一个和第二个最大值都是 6,所以它忽略了 5。

最佳做法是抛出所有重复值 - 您可以使用 python 内置函数来执行此操作 (set)。然后尝试运行你的代码。

第二种方法是将第一个最大值作为第一个元素,第二个作为-1,所以当你第一次遇到比它设置的最大值更大的元素时。如果循环结束并且第二个最大值仍然是-1,则意味着所有元素都相同

【讨论】:

    【解决方案3】:

    这是一种不同的方法:将数据转换为集合(从而删除重复元素),删除最大值,然后打印最大值。例如:

    data = [6,6,6,6,6,6,6,6,6,5]
    sb = set(data) # remove duplicate elements
    sb.remove(max(sb)) # remove the max element
    print(max(sb)) # print the new max
    

    输出:

    5
    

    如果您只想删除重复元素,请将集合转换回列表:

    data = [6,6,6,6,6,6,6,6,6,5]
    data = list(set(data))
    

    输出:

    >>> data
    [5, 6]
    

    【讨论】:

      【解决方案4】:
      def second_biggest(l):
        """ Get second biggest entry in a list
      
          1. make a `set` out of `list`: guarantees that every entry only appears once
          2. sort the `set` by value
          3. get the second biggest entry
        """
        return sorted(set(l))[-2]
      

      【讨论】:

      • 那行得通。但我想知道一般逻辑,而不是特定于语言的解决方案。
      • 我不明白你所说的“一般逻辑”是什么意思。使所有条目唯一,排序并从排序列表中获得第二大条目是您需要在所有编程语言中应用的“一般逻辑”。
      • 如何在 C 中应用它?我是初学者。
      • 很好地解释了这一切。但也许如果您阅读how to implement a set datastructuresorting algorithms,您会有所了解。希望这可以帮助。继续努力,学习编程非常有价值,每一分钟的投入最终都会得到回报。
      【解决方案5】:

      您可以尝试使用sorted 方法进行排序,然后通过转换为设置删除重复元素找到第二大元素,然后选择倒数第二个元素。

      arr = [2, 4, 5, 5, 455, 34]
      unique_arr = sorted(set(arr))
      
      print(unique_arr[-2])
      

      编辑:
      不使用pythonsetsorted函数:

      arr = [1, 4, 5, 723, 64, 76, 34]
      
      max_1 = max(arr)
      max_2 = min(arr)
      
      for item in arr:
          if item > max_2 and item != max_1:
              max_2 = item
      
      print("Second largest item: ", max_2)
      

      【讨论】:

        【解决方案6】:

        试试:

        list1 = list(arr)
            
            
        new_set = set(list1)
            
            
        new_list = list(new_set)
        new_list.sort()
            
            
        new_list.pop(-1)
            
        print(new_list[-1])
        

        【讨论】:

          【解决方案7】:

          由于最大值可能多次出现,我们在列表中找到最大值并创建一个没有最大值的列表。然后我们从新列表中找到最大值,这给了我们第二大的值。

             n = int(input("Enter the total numbers: "))
             arr = list(map(int, input("Enter the numbers: ").split()))
          
             max_val = max(arr)
          
             lst = [x for x in arr if x!=max_val]
             second_max = max(lst) 
             
             print(second_max)
          

          【讨论】:

          • 请写下您发布的代码背后的原因。为什么它会这样做。
          • 很抱歉给您带来不便。添加了解释:)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-03
          • 1970-01-01
          • 2016-03-19
          • 2019-11-06
          • 1970-01-01
          • 2021-01-01
          相关资源
          最近更新 更多