在有序数组中找到小于 x 的最大值

Posted

技术标签:

【中文标题】在有序数组中找到小于 x 的最大值【英文标题】:Find the largest value smaller than x in a sorted array 【发布时间】:2011-03-30 09:38:12 【问题描述】:

假设我有一个排序的整数数组int[],我想搜索最接近某个输入数字的较小值。

例如,如果数组包含 (1) , (23), (57) , (59), (120) 并且输入为 109,则输出应为 59。

我只是想看看建议并与我已有的方法进行比较。

【问题讨论】:

【参考方案1】:

使用Array.BinarySearch。如果输入在列表中,它将返回索引,如果不是,则返回第一个较大值的索引的补码。您只需反转结果并减去一个以获得最接近的较小值的索引。

int[] arr =  1, 23, 57, 59, 120 ;
int index = Array.BinarySearch(arr, 109);
if (index < 0)

    index = ~index - 1;

if (index >= 0)

    var result = arr[index];

请注意,如果您的输入小于最小元素,则您没有明确定义的答案。

【讨论】:

(index >= 0) 如果不是真的,什么时候会在最后? (不,我不是在寻找索引小于零时:P) @Rune FS:尝试搜索 0。~index 将是 0,因为 1 是次高的数字,所以 ~index - 1 将是 -1。没有比输入小的元素,所以没有有效的答案。 对于Java,使用Arrays.binarySearch(大小写不同)【参考方案2】:

使用 Linq:

int[] arr = new[]  1, 23, 57, 59, 120 ;
int target = 109;
int max = arr.Where(n => n < target).Max();

也许不是最快的,但可能是最容易实现的。也不像二分搜索那样依赖被排序的数组。

请注意,如果Where 过滤器没有生成任何元素,则对Max 的调用将引发异常,因此您可能需要检查是否有可能。

【讨论】:

可能重复:P ***.com/questions/3492840/… mustapha - 可爱 :).. 顺便说一句,因为它们非常相似,所以更新了我的更新以显示恐惧的建议重新检查异常【参考方案3】:

我会选择 linq 解决方案(更新:添加更多代码以防止与恐惧的类似解决方案相似):

int[] arr1 =  1, 23, 57, 59, 120 ;
int maxResult;
string errorMsg;
try

    maxResult = arr1.Where(x => x <= 109).Max();

catch(Exception e)

    errorMsg = e.Message;
    // do some error stuff here :)
    return null;

// party on your maxResult...

【讨论】:

【参考方案4】:
int getIndex( long[] list, long value )

    int top = 0;
    int bot = list.length-1;
    int mid=0;
    while ( top <= bot )
    
        mid = (top+bot)/2; // NB integer arithmetic
        if ( value < list[mid] )
        
            if ( mid == 0 )
                // value < than first item
                return -1;  
            else
                bot = mid-1;
        
        else    // value >= list[mid]
        
            if ( mid == list.length-1 )
                // value is >= last item
                break;
            else if ( value >= list[mid+1] )
                top = mid+1;
            else // list[mid] must be biggest <= value
                break;
        
    
    return mid;

【讨论】:

【参考方案5】:

只是为了推断其他 LINQ 解决方案,如果没有对象适合过滤器并期望列表都是正整数,则此扩展方法将返回 -1

public static int SearchForLimit(this IEnuemerable<int> sequence, Predicate<int> filter)

   return (from i in sequence
           let n = filter(i) ? i : -1
           select n).Max()

用法如下所示:

int[] arr1 =  1, 23, 57, 59, 120 ;
int limitedBy109 = arr1.SearchForLimit(i => i < 109);

【讨论】:

以上是关于在有序数组中找到小于 x 的最大值的主要内容,如果未能解决你的问题,请参考以下文章

分而治之算法找到两个有序元素之间的最大差异

分而治之以找到二维数组中两个有序元素之间的最大差异

P1043 查找小于x的最大元素

在 O(logn) 中找到三个有序数组的中位数

python面试题-找到两个数组元素和小于等于目标值target的最大值的所有组合

测试题目:两个有序数组,找出最大的五个数字组成一个新的数组