Я знаю, что это очень старый пост. Тем не менее, я работал над проблемой, и я наткнулся на этот пост. Я хотел бы добавить свою итеративную версию для задачи, которая является расширением последнего ответа. Я проверил это с помощью тестовых случаев, которые я мог придумать. Я приложил свой код в 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