给定一个已排序的数组和一个目标值,找到严格小于给定元素的第一个元素。
例子:
Input : arr[] = {1, 2, 3, 5, 8, 12}
Target = 5
Output : 2 (Index of 3)
Input : {1, 2, 3, 5, 8, 12}
Target = 8
Output : 3 (Index of 5)
Input : {1, 2, 3, 5, 8, 12}
Target = 15
Output : -1
一个简单的解决方案是线性遍历给定数组并找到严格大于第一个元素。如果不存在这样的元素,则返回-1。
一个有效的解决方案是使用二进制搜索。在一般的二进制搜索中,我们正在寻找出现在数组中的值。但是,有时我们需要找到第一个大于目标的元素。
要查看该算法是否正确,请考虑进行每个比较。如果我们发现一个大于目标元素的元素,则该元素及其上方的所有内容可能都不匹配,因此无需搜索该区域。因此,我们可以搜索左半部分。如果我们发现一个小于所讨论元素的元素,那么它之前的任何内容也必须更大,因此它们不能成为第一个更小的元素,因此我们不需要搜索它们。因此,中间元素是它最后可能出现的位置。
请注意,在每次迭代中,我们会至少考虑其余元素的一半。如果执行顶部分支,则[low,(low + high)/ 2]范围内的元素都将被丢弃,从而使我们损失底价((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 the left side if the target is smaller
if (arr[mid] >= target)
{
end = mid - 1;
}
// Move right side
else
{
ans = mid;
start = 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, 5, n));
return 0;
}
// This code is contributed by Rajput-Ji
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 the left side if the target is smaller
if (arr[mid] >= target) {
end = mid - 1;
}
// Move right side
else {
ans = mid;
start = 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, 5));
}
}
Python3
# Python3 program to find first element that
# is strictly smaller than given target
def next(arr, target):
start = 0;
end = len(arr) - 1;
ans = -1;
while (start <= end):
mid = (start + end) // 2;
# Move to the left side if target is
# smaller
if (arr[mid] >= target):
end = mid - 1;
# Move right side
else:
ans = mid;
start = mid + 1;
return ans;
# Driver code
if __name__ == '__main__':
arr = [ 1, 2, 3, 5, 8, 12 ];
print(next(arr, 5));
# This code is contributed by Yash_R
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 the left side if the target is smaller
if (arr[mid] >= target) {
end = mid - 1;
}
// Move right side
else {
ans = mid;
start = mid + 1;
}
}
return ans;
}
// Driver code
public static void Main()
{
int[] arr = { 1, 2, 3, 5, 8, 12 };
Console.WriteLine(next(arr, 5));
}
}
// This code is contributed by Code_Mech.
PHP
= $target)
{
$end = $mid - 1;
}
// Move right side
else
{
$ans = $mid;
$start = $mid + 1;
}
}
return $ans;
}
// Driver code
{
$arr = array(1, 2, 3, 5, 8, 12 );
echo(next0($arr, 5));
}
// This code is contributed by Code_Mech.
输出:
2