C 在数组中查找最接近0的负数(日志n复杂性)

C 在数组中查找最接近0的负数(日志n复杂性),c,C,我有一个问题:写一个函数,得到一个整数及其大小的升序数组。 假设数组至少包含一个负数和一个正数,我需要找到与该数字最近的负数0。 例如:[-30,-25,-18,-10,11,11,20,30] 该函数将返回-10. 问题是,我需要在O(logn)复杂度中完成,我不知道如何完成。 我是用O(n)做的。 ` intf(int*arr,int-size) { int i; int result=arr[0]; 对于(i=1;i=0?&top:&bot)=mid,但会同情学生。(C++中,你可以不使用

我有一个问题:写一个函数,得到一个整数及其大小的升序数组。 假设数组至少包含一个负数和一个正数,我需要找到与该数字最近的负数
0。

例如:
[-30,-25,-18,-10,11,11,20,30]

该函数将返回
-10.

问题是,我需要在
O(logn)
复杂度中完成,我不知道如何完成。 我是用
O(n)做的。

`

intf(int*arr,int-size)
{
int i;
int result=arr[0];
对于(i=1;i

}这里是一个简单的二进制搜索的C实现,它在O(logn)时间内工作


这里是一个简单的二进制搜索的C实现,它在O(logn)时间内工作

这里有一个可能的方法

int f( int *n, int size )
{
    int low = 0, mid, high = size-1;
        
    while( (mid = (low+high)/2) && n[mid] * n[mid+1] > 0 ) n[mid] < 0 ? (low = mid) : (high = mid);
    
    return n[mid] ? n[mid] : n[mid-1];
}
编辑:我忘了告诉您,因为函数的算法是a,所以它适合您的时间复杂度要求。

这里有一种可能的方法

int f( int *n, int size )
{
    int low = 0, mid, high = size-1;
        
    while( (mid = (low+high)/2) && n[mid] * n[mid+1] > 0 ) n[mid] < 0 ? (low = mid) : (high = mid);
    
    return n[mid] ? n[mid] : n[mid-1];
}


编辑:我忘了告诉你,因为函数的算法是a,它适合你的时间复杂度要求。

因为数组保证可以排序,你可以利用这些信息。你不需要遍历整个数组。遍历,直到你得到一个整数,使用二进制搜索?从中间开始并保持细分。因为它被排序,你知道中间答案的中间部分。Nick和适应STD::从C++标准库实现中的LoeReLyLang.因为数组保证被排序,你可以利用这些信息。你不需要遍历整个数组。遍历,直到你得到一个整数,使用二进制搜索?从中间开始并保持细分。因为它已经排序,你知道中间答案的中间部分。Nick和适应STD::从C++标准库实现中的下限。由于您的目标是健壮性,您应该解决。看看std::midpoint是如何在c++20标准库实现中实现的。真诚地向上投票-我相信你会的!由于给定数组包含至少一个正数,
top
可以初始化为
size-1
。(这是对所述问题的补充练习:不是寻找最大的负数,而是寻找最小的正优化。)我倾向于将整个
if
语句替换为
*(arr[mid]>=0?&top:&bot)=mid,但会同情学生。(C++中,你可以不使用<代码> */COD>和<代码>和<代码>,但是C不允许LVales。)它在功能上是等价的。我自己的偏好是不使用三元运算符。如果使用
查找易于阅读和维护的代码,如果。。。否则
.bot+top容易溢出。由于您的目标是健壮性,您应该解决。看看std::midpoint是如何在c++20标准库实现中实现的。真诚地向上投票-我相信你会的!由于给定数组包含至少一个正数,
top
可以初始化为
size-1
。(这是对所述问题的补充练习:不是寻找最大的负数,而是寻找最小的正优化。)我倾向于将整个
if
语句替换为
*(arr[mid]>=0?&top:&bot)=mid,但会同情学生。(C++中,你可以不使用<代码> */COD>和<代码>和<代码>,但是C不允许LVales。)它在功能上是等价的。我自己的偏好是不使用三元运算符。如果使用
查找易于阅读和维护的代码,如果。。。else
-10
int f( int *n, int size )
{
    int low = 0, mid, high = size-1;
        
    while( (mid = (low+high)/2) && n[mid] * n[mid+1] > 0 ) n[mid] < 0 ? (low = mid) : (high = mid);
    
    return n[mid] ? n[mid] : n[mid-1];
}
while( !n[mid] ) --mid;