在列表中查找小于或等于键的值

Posted

技术标签:

【中文标题】在列表中查找小于或等于键的值【英文标题】:finding a value in a list just less than or equal to key 【发布时间】:2019-09-27 02:45:54 【问题描述】:

给定一个排序数组,我想获得等于或小于传递的键的最小元素

我已经尝试在每个元素之间找到间隙并返回间隙最小的那个,但这并没有给出预期的结果,因为它还返回大于传递的值

sorted_li= [25,22,15,14,12,6,4]
def find_nearest_small_value(key,sorted_li):
    gap_current, gap_global, value = 0, key, sorted_li[0]
    for i in sorted_li:
        gap_current = abs(i-key)
        if gap_global>=gap_current:
            gap_global=gap_current
            value=i
    return value

例如,上面带有 key=19 的代码将返回 22,因为那里的间隙是 3,尽管它应该返回 15,因为它小于 19,并且间隙最小

任何帮助将不胜感激谢谢:)

【问题讨论】:

听起来你使用了错误的“差距”计算然后...... 这段代码总是返回 4... 你的意思是return value吗? @cricket_007 是的,你是对的,虽然这是一个错字,但它仍然没有返回所需的输出 我不知道你为什么认为你需要计算差距。迭代时可以返回立即小于或等于key的元素 你字面意思是给定一个排序数组。如果您有一个未排序的数组,那么这是一个单独的问题 【参考方案1】:

这适用于已排序和未排序的输入序列:

def find_nearest_small_value(key, sorted_li):
    return max(i for i in sorted_li if i <= key)

它非常容易阅读和简单的解决方案

【讨论】:

这是 O(N),与包含排序的解决方案相比(即 O(NlogN)) 非常正确。虽然这是一种选择。它可能不是最好的选择 真的吗?我认为在某些情况下 O(NlogN)) 可能比 O(n) 更快,还是我错了? 我不确定你是否可以找到N 的值来制作O(N) &gt; O(NlogN) =)【参考方案2】:

天真的方法

遍历给定排序列表中的每个元素,并在满足条件时返回该元素。最坏的情况复杂度是O(n)

def find_nearest_small_value(key, sorted_li):
    for i in sorted_li:
        if i <= key:
            return i
    return None

高效方法:二分查找

每次比较时将搜索空间减半,从而使算法更高效。复杂度为O(log n)

def find_nearest_small_value(key, sorted_li):
    element = None
    start = 0
    end = len(sorted_li)
    while start <= end:
        mid = (start + end) // 2
        if mid >= len(sorted_li):  # out of bounds
            break
        if sorted_li[mid] <= key:
            element = sorted_li[mid]
            end = mid - 1
        else:
            start = mid + 1
    return element

【讨论】:

是的,这行得通。虽然我应该提到未排序列表的可能性 您的 for 循环将在成功的情况下精确地进行 1(一)次迭代,或者如果所有值都大于 key,则毫无意义地循环直到结束。 是的,我还假设给定的排序列表按降序排序(从大到小)。如果列表未排序,您始终可以先使用列表中的sorted(list, reverse=True)。但是,这会增加算法的时间复杂度。【参考方案3】:

为什么有人需要一个循环呢?如果小于keyNone,则将第一个元素作为最小元素返回:

def find_nearest_small_value( key, sorted_list ) :
    return sorted_list[0] if sorted_list[0] <= key else None

回答以下问题:

>>> def find_nearest_small_value( key, sorted_list ) :
...     return sorted_list[0] if sorted_list[0] <= key else None
... 
>>> find_nearest_small_value( 31, [22,25,28,39] )
22

【讨论】:

你应该如何检查每个元素而不检查所有元素 @abhay 在排序后的数组中最小的元素是第一个,为什么我需要检查所有的? 如果 li = [22,25,28,39] 并且我给 key=31 它会返回 22 虽然所需的输出是 28 也许我应该问我的问题是返回小于或等于列表中给定键的最大元素 @abhay 看到编辑,一切正常。

以上是关于在列表中查找小于或等于键的值的主要内容,如果未能解决你的问题,请参考以下文章

二分查找

python使用heapq快速查找最大或最小的 N 个元素

红黑树解析

二叉查找树(BST)的性质

红黑树原理分析

二叉排序树