我知道这是一个非常古老的帖子。但是,我正在解决一个问题,并且遇到了这篇文章。我想为这个问题添加我的迭代版本,这是最后一个答案的扩展。我用我能想到的测试用例检查了这一点。我在 C# 中附加了我的代码。
此代码适用于所有范围。但是,范围应该在第一个索引到最后一个索引+1 之间。如果数组的大小为 N 并且考虑范围为 [0,N],则搜索空间将在 [0,N) 内。我知道这很明显,但它帮助我检查了一些边缘情况。
static int lower_bound(int[] a, int lo,int hi, int x)
{
while (lo < hi)
{
int mid = lo + (hi-lo) / 2;
if(a[mid]==x)
{
/*when there is a match, we should keep on searching
for the next same element. If the same element is not
found, mid is considered as the answer and added to 'hi'
Finally 'hi' is returned*/
if(a[mid-1]!=x)
{
hi=mid;
break;
}
else
hi=mid-1;
}
else if(a[mid]>x)
hi=mid-1;
else
lo=mid+1;
}
//if element is not found, -1 will be returned
if(a[hi]!=x)
return -1;
return hi;
}
static int upper_bound(int[] a, int lo,int hi, int x)
{
int temp=hi;
while (lo < hi)
{
int mid = lo + (hi-lo) / 2;
if(a[mid]==x)
{
/*this section make sure that program runs within
range [start,end)*/
if(mid+1==hi)
{
lo=mid;
break;
}
/*when there is a match, we should keep on searching
for the next same element. If the same element is not
found, mid is considered as the answer and added to
'lo'. Finally 'lo' is returned*/
if(a[mid+1]!=x)
{
lo=mid;
break;
}
else
lo=mid+1;
}
else if(a[mid]>x)
hi=mid-1;
else
lo=mid+1;
}
//if element is not found, -1 will be returned
if(a[lo]!=x)
return -1;
return lo;
}
这是我使用的一个测试用例:
Array(a) : 1 2 2 2 2 5 5 5 5
size of the array(a) : 9
将搜索元素视为 2:
upper_bound(a,0,9,2)=4, lower_bound(a,0,9,2)=1
将搜索元素视为 5:
upper_bound(a,0,9,2)=8, lower_bound(a,0,9,2)=5
将搜索元素视为 1:
upper_bound(a,0,9,2)=0, lower_bound(a,0,9,2)=0
将搜索元素视为 5:
upper_bound(a,5,9,2)=8, lower_bound(a,5,9,2)=5