给定一个排序数组和一个目标值,找到第一个严格大于给定元素的元素。
例子:
Input : arr[] = {1, 2, 3, 5, 8, 12}
Target = 5
Output : 4 (Index of 8)
Input : {1, 2, 3, 5, 8, 12}
Target = 8
Output : 5 (Index of 12)
Input : {1, 2, 3, 5, 8, 12}
Target = 15
Output : -1
一个简单的解决方案是线性遍历给定数组并找到第一个严格大于的元素。如果不存在这样的元素,则返回 -1。
一个有效的解决方案是使用二分搜索。在一般的二分搜索中,我们正在寻找出现在数组中的值。然而,有时我们需要找到第一个大于目标的元素。
要查看此算法是否正确,请考虑进行的每个比较。如果我们找到一个不大于目标元素的元素,那么它和它下面的所有元素都不可能匹配,所以不需要搜索那个区域。因此,我们可以搜索右半部分。如果我们发现一个元素比所讨论的元素大,那么它之后的任何元素也必须更大,所以它们不能是第一个更大的元素,所以我们不需要搜索它们。因此,中间元素是它可能出现的最后一个位置。
请注意,在每次迭代中,我们至少放弃了一半的剩余元素。如果 top 分支执行,那么 [low, (low + high) / 2] 范围内的元素都被丢弃,导致我们失去 floor((low + high) / 2) – low + 1 >= (low +高) / 2 – 低 = (高 – 低) / 2 个元素。
如果底部分支执行了,那么[(low + high) / 2 + 1, high]范围内的元素都被丢弃。这让我们失去了高 – 地板(低 + 高)/ 2 + 1 > = 高 – (低 + 高)/ 2 =(高 – 低)/ 2 个元素。
因此,我们最终会在这个过程的 O(lg n) 次迭代中找到大于目标的第一个元素。
C++
// C++ program to find first element that
// is strictly greater than given target.
#include
using namespace std;
int next(int arr[], int target, int end)
{
int start = 0;
int ans = -1;
while (start <= end)
{
int mid = (start + end) / 2;
// Move to right side if target is
// greater.
if (arr[mid] <= target)
start = mid + 1;
// Move left side.
else
{
ans = mid;
end = mid - 1;
}
}
return ans;
}
// Driver code
int main()
{
int arr[] = {1, 2, 3, 5, 8, 12};
int n = sizeof(arr) / sizeof(arr[0]);
cout << next(arr, 8, n);
return 0;
}
// This code is contributed by sanjeev2552
Java
// Java program to find first element that
// is strictly greater than given target.
class GfG {
private static int next(int[] arr, int target)
{
int start = 0, end = arr.length - 1;
int ans = -1;
while (start <= end) {
int mid = (start + end) / 2;
// Move to right side if target is
// greater.
if (arr[mid] <= target) {
start = mid + 1;
}
// Move left side.
else {
ans = mid;
end = mid - 1;
}
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int[] arr = { 1, 2, 3, 5, 8, 12 };
System.out.println(next(arr, 8));
}
}
Python3
# Python program to find first element that
# is strictly greater than given target.
def next(arr, target):
start = 0;
end = len(arr) - 1;
ans = -1;
while (start <= end):
mid = (start + end) // 2;
# Move to right side if target is
# greater.
if (arr[mid] <= target):
start = mid + 1;
# Move left side.
else:
ans = mid;
end = mid - 1;
return ans;
# Driver code
if __name__ == '__main__':
arr = [1, 2, 3, 5, 8, 12];
print(next(arr, 8));
# This code is contributed by 29AjayKumar
C#
// C# program to find first element that
// is strictly greater than given target.
using System;
class GfG
{
private static int next(int[] arr, int target)
{
int start = 0, end = arr.Length - 1;
int ans = -1;
while (start <= end)
{
int mid = (start + end) / 2;
// Move to right side if target is
// greater.
if (arr[mid] <= target)
{
start = mid + 1;
}
// Move left side.
else
{
ans = mid;
end = mid - 1;
}
}
return ans;
}
// Driver code
public static void Main()
{
int[] arr = { 1, 2, 3, 5, 8, 12 };
Console.WriteLine(next(arr, 8));
}
}
// This code is contributed by Code_Mech
PHP
Javascript
5
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。