给定一个由N 个整数组成的排序数组 arr[]和一个数字K ,任务是编写 C 程序以在给定数组中找到 K的 upper_bound() 和 lower_bound()。
例子:
Input: arr[] = {4, 6, 10, 12, 18, 20}, K = 6
Output:
Lower bound of 6 is 6 at index 1
Upper bound of 6 is 10 at index 2
Input: arr[] = {4, 6, 10, 12, 18, 20}, K = 20
Output:
Lower bound of 20 is 20 at index 5
Upper bound doesn’t exist
方法:这个想法是使用二分搜索。以下是步骤:
- 对于lower_bound():
- 将startIndex初始化为0 ,将endIndex初始化为N – 1 。
- 将K与数组的中间元素(比如arr[mid] )进行比较。
- 如果中间元素大于等于K,则将 endIndex 更新为中间索引( mid )。
- 否则将 startIndex 更新为 mid + 1。
- 重复以上步骤直到startIndex小于endIndex 。
- 在上述所有步骤之后, startIndex是给定数组中K的下界。
- 对于上限():
- 将startIndex初始化为0 ,将endIndex初始化为N – 1 。
- 将K与数组的中间元素(比如arr[mid] )进行比较。
- 如果中间元素小于等于K,则将 startIndex 更新为中间索引 + 1( mid + 1)。
- 否则将 endIndex 更新为 mid。
- 重复以上步骤直到startIndex小于endIndex 。
- 在所有的上述步骤的startIndex是K的给定阵列中的UPPER_BOUND。
下面是上述方法的迭代和递归实现:
Iterative Solution
// C program for iterative implementation
// of the above approach
#include
// Function to implement lower_bound
int lower_bound(int arr[], int N, int X)
{
int mid;
// Initialise starting index and
// ending index
int low = 0;
int high = N;
// Till low is less than high
while (low < high) {
mid = low + (high - low) / 2;
// If X is less than or equal
// to arr[mid], then find in
// left subarray
if (X <= arr[mid]) {
high = mid;
}
// If X is greater arr[mid]
// then find in right subarray
else {
low = mid + 1;
}
}
// if X is greater than arr[n-1]
if(low < N && arr[low] < X) {
low++;
}
// Return the lower_bound index
return low;
}
// Function to implement upper_bound
int upper_bound(int arr[], int N, int X)
{
int mid;
// Initialise starting index and
// ending index
int low = 0;
int high = N;
// Till low is less than high
while (low < high) {
// Find the middle index
mid = low + (high - low) / 2;
// If X is greater than or equal
// to arr[mid] then find
// in right subarray
if (X >= arr[mid]) {
low = mid + 1;
}
// If X is less than arr[mid]
// then find in left subarray
else {
high = mid;
}
}
// if X is greater than arr[n-1]
if(low < N && arr[low] <= X) {
low++;
}
// Return the upper_bound index
return low;
}
// Function to implement lower_bound
// and upper_bound of X
void printBound(int arr[], int N, int X)
{
int idx;
// If lower_bound doesn't exists
if (lower_bound(arr, N, X) == N) {
printf("Lower bound doesn't exist");
}
else {
// Find lower_bound
idx = lower_bound(arr, N, X);
printf("Lower bound of %d is"
"% d at index % d\n ",
X,
arr[idx], idx);
}
// If upper_bound doesn't exists
if (upper_bound(arr, N, X) == N) {
printf("Upper bound doesn't exist");
}
else {
// Find upper_bound
idx = upper_bound(arr, N, X);
printf("Upper bound of %d is"
"% d at index % d\n ",
X,
arr[idx], idx);
}
}
// Driver Code
int main()
{
// Given array
int arr[] = { 4, 6, 10, 12, 18, 20 };
int N = sizeof(arr) / sizeof(arr[0]);
// Element whose lower bound and
// upper bound to be found
int X = 6;
// Function Call
printBound(arr, N, X);
return 0;
}
Recursive Solution
// C program for recursive implementation
// of the above approach
#include
// Recursive implementation of
// lower_bound
int lower_bound(int arr[], int low,
int high, int X)
{
// Base Case
if (low > high) {
return low;
}
// Find the middle index
int mid = low + (high - low) / 2;
// If arr[mid] is greater than
// or equal to X then search
// in left subarray
if (arr[mid] >= X) {
return lower_bound(arr, low,
mid - 1, X);
}
// If arr[mid] is less than X
// then search in right subarray
return lower_bound(arr, mid + 1,
high, X);
}
// Recursive implementation of
// upper_bound
int upper_bound(int arr[], int low,
int high, int X)
{
// Base Case
if (low > high)
return low;
// Find the middle index
int mid = low + (high - low) / 2;
// If arr[mid] is less than
// or equal to X search in
// right subarray
if (arr[mid] <= X) {
return upper_bound(arr, mid + 1,
high, X);
}
// If arr[mid] is greater than X
// then search in left subarray
return upper_bound(arr, low,
mid - 1, X);
}
// Function to implement lower_bound
// and upper_bound of X
void printBound(int arr[], int N, int X)
{
int idx;
// If lower_bound doesn't exists
if (lower_bound(arr, 0, N, X) == N) {
printf("Lower bound doesn't exist");
}
else {
// Find lower_bound
idx = lower_bound(arr, 0, N, X);
printf("Lower bound of %d "
"is %d at index %d\n",
X, arr[idx], idx);
}
// If upper_bound doesn't exists
if (upper_bound(arr, 0, N, X) == N) {
printf("Upper bound doesn't exist");
}
else {
// Find upper_bound
idx = upper_bound(arr, 0, N, X);
printf("Upper bound of %d is"
"% d at index % d\n ",
X,
arr[idx], idx);
}
}
// Driver Code
int main()
{
// Given array
int arr[] = { 4, 6, 10, 12, 18, 20 };
int N = sizeof(arr) / sizeof(arr[0]);
// Element whose lower bound and
// upper bound to be found
int X = 6;
// Function Call
printBound(arr, N, X);
return 0;
}
输出:
Lower bound of 6 is 6 at index 1
Upper bound of 6 is 10 at index 2
时间复杂度: O(log 2 N) ,其中 N 是数组中的元素数。
想要从精选的视频和练习题中学习,请查看 C 基础到高级C 基础课程。