简体   繁体   English

如何使用 lopps 找到给定值的一对搜索值?

[英]How to find a pair of hunted values for a given value with lopps?

I am trying to write a function that gets a list of numbers and an integer and returns a tuple that containing pair of numbers from the list whose sum is the must closest to the number the function received.我正在尝试编写一个函数,该函数获取一个数字列表和一个整数,并返回一个元组,该元组包含列表中的一对数字,其总和必须最接近函数接收到的数字。 for example: closest([10,22,28,29,30,40], 54) --> (22,30) It is important for me to do this in loop and in time complexity of O(n).例如:closest([10,22,28,29,30,40], 54) --> (22,30) 在循环和 O(n) 的时间复杂度中执行此操作对我来说很重要。 The problem with my code is that the loop does not want to rerun the list end for any value I take from the beginning of the list... I would appreciate help :) Thanks for the helpers!我的代码的问题是循环不想为我从列表开头获取的任何值重新运行列表结尾......我很感激帮助:) 感谢帮助者!

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)

The important part that you might not have noticed is that your input list is sorted.您可能没有注意到的重要部分是您的输入列表已排序。

10,22,28,29,30,40

Which means you can take advantage of this information to find the pair you're looking for in a single scan of the list.这意味着您可以利用此信息在列表的单次扫描中找到您正在寻找的配对。 The intuition is that if you need a larger number, you can go towards the end of the list.直觉是,如果你需要更大的数字,你可以走到列表的末尾。 These kind of solutions are referred to as the two-pointer technique这些解决方案被称为两点技术

The problem you're trying to solve is a variant of the 2SUM problem .您要解决的问题是2SUM 问题的变体。 There are solutions online such as here网上有解决办法,比如这里

However I would suggest that you read through the first couple of links & try to solve it by yourself.但是,我建议您通读前几个链接并尝试自己解决。

By using the itertools module and a dictionary where the keys are the sums of the pairs and the values are lists of pairs:通过使用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)]

如果您提供的列表已排序并且元素是唯一的,您可以使用 this.Otherwise 我相信您可以对字典实施一些条件并获得您想要的值。

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)]

Since you require tuples of exactly 2 elements this can be done with numpy to find the pair of points that are closest to x.由于您需要恰好 2 个元素的元组,因此可以使用numpy来找到最接近 x 的点对。 Do the outer addition of the list with itself, find the closest absolute distance to 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)

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

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