【问题标题】:How to find a pair of hunted values for a given value with lopps?如何使用循环找到给定值的一对搜寻值?
【发布时间】:2020-02-17 14:02:15
【问题描述】:

我正在尝试编写一个函数,该函数获取一个数字列表和一个整数,并返回一个元组,该元组包含列表中的一对数字,其总和必须与函数接收到的数字最接近。 例如:最近([10,22,28,29,30,40], 54) --> (22,30) 在循环和 O(n) 的时间复杂度中这样做对我来说很重要。 我的代码的问题是循环不想为我从列表开头获取的任何值重新运行列表结束... 我会很感激帮助:) 感谢帮助!

def closest(lst, x):
    max_num = 0
    cur = lst[0]
    final = 0
    my_tup = ()
    for num in lst[::-1]:
        max_num = cur + num
        if max_num <= x:
            if max_num > final:
                final = max_num
                my_tup = (cur, num)
            else:
                cur = lst[1]

    return my_tup

print(closest([10,22,28,29,30,40], 54))  ---> return: (22,29)

【问题讨论】:

    标签: python list tuples


    【解决方案1】:

    您可能没有注意到的重要部分是您的输入列表已排序。

    10,22,28,29,30,40
    

    这意味着您可以利用此信息在单次扫描列表中找到您要查找的配对。直觉是,如果您需要更大的数字,您可以走到列表的末尾。这类解决方案被称为two-pointer technique

    您要解决的问题是2SUM problem 的变体。网上有解决办法如here

    但是,我建议您通读前几个链接并尝试自己解决。

    【讨论】:

      【解决方案2】:

      通过使用itertools 模块和字典,其中键是对的总和,值是对的列表:

      from itertools import combinations
      
      
      def closest(lst, val):
          d = {}
          for element in combinations(lst, 2):
              elem_sum = sum(element)
              try:
                  d[elem_sum].append(element)
              except KeyError:
                  d[elem_sum] = [element]
          return d[min(d, key=lambda x: abs(x-val))]
      
      
      >>> closest([10, 22, 28, 29, 30, 40], 54)
      [(22, 30)]
      

      【讨论】:

        【解决方案3】:

        如果你给出的列表是排序好的并且元素是唯一的你可以使用这个。否则我相信你可以对字典实现一些条件并得到你想要的值。

        my_dict = {i+j:(i,j) for i in mylist for j in mylist if i != j and i + j < bound} my_dict[max(t)]

        【讨论】:

        • 这是O(n^2) ?
        • 您将以 (22, 30) 和 (30, 22) 等重复项结尾
        【解决方案4】:

        由于您需要正好包含 2 个元素的元组,因此可以使用 numpy 来找到最接近 x 的点对。将列表与自身进行外部添加,找到最接近 x 的绝对距离。

        import numpy as np
        
        def closest(lst, x):
            arr = np.array(lst)
            mat = np.abs(x - (arr[:, None] + arr)).astype(float)
            mat[np.diag_indices_from(mat)] = np.NaN # Exclude tuples of same point with itself 
            i,j = np.unravel_index(np.nanargmin(mat), mat.shape)
        
            return arr[i], arr[j]
        
        closest([10,22,28,29,30,40], 54)
        (22, 30)
        
        closest([10,27,28,29,30,40], 54)
        (27, 28)
        

        【讨论】:

          猜你喜欢
          • 2011-04-25
          • 2023-02-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-05
          相关资源
          最近更新 更多