什么是二进制搜索算法?
二进制搜索算法用于查找x的某个值,为此需要将某个定义的函数f(x)最大化或最小化。通过将搜索间隔重复分成两半,它经常用于按排序顺序搜索元素。从一个覆盖整个序列的间隔开始,如果搜索关键字的值小于间隔中间的项目,则在间隔的左半部分进行搜索,否则在右半部分进行搜索。重复检查,直到找到该值或间隔为空。
执行二进制搜索的主要条件是序列必须是单调的,即,它必须是递增或递减的。
Monotonic function
A function f(x) is said to be monotonic if and only if for any x if f(x) returns true, then for any value of y (where y > x) should also return true and similarly if for a certain value of x for which f(x) is false, then for any value z (z < x) the function should also return false.
如何使用Binary Search解决问题:
如果函数是
而任务是找到x的最大值,以使f(x)小于或等于目标值。我们将搜索给定目标值的时间间隔
从0到目标值。
然后我们可以使用二进制搜索来解决这个问题,因为该函数
是单调增加的函数。
Target = 17
f(x) = x2, since the function is monotonic binary search can be applied to it.
Range of search interval will be [0, target]
Step 1:
low = 0, high = 17, calculate mid = (low + high)/2 = 8
Calculate f(8) = 64 which is more than target, so it will return false and high will be updated as high = mid – 1 = 7.
Steps 2:
low = 0, high = 7, calculate mid = (low + high)/2 = 3
Calculate f(3) = 9 which is less than target, so it will return true and low will be updated as low = mid + 1 = 4.
Step 3:
low = 4, high = 7, calculate mid = (low + high)/2 = 5
Calculate f(5) = 25 which is more than target, so it will return false and high will be updated as high = mid – 1 = 4.
Step 4:
Now since the range [low, high] converges to a single point i.e 4 so the final result is found, since f(4) = 16 which is the maximum value of the given function less than target.
下面是上述示例的实现:
C++
// C++ program for the above example
#include "bits/stdc++.h"
using namespace std;
// Function to find X such that it is
// less than the target value and function
// is f(x) = x^2
void findX(int targetValue)
{
// Initialise start and end
int start = 0, end = targetValue;
int mid, result;
// Loop till start <= end
while (start <= end) {
// Find the mid
mid = start + (end - start) / 2;
// Check for the left half
if (mid * mid <= targetValue) {
// Store the result
result = mid;
// Reinitialize the start point
start = mid + 1;
}
// Check for the right half
else {
end = mid - 1;
}
}
// Print the maximum value of x
// such that x^2 is less than the
// targetValue
cout << result << endl;
}
// Driver Code
int main()
{
// Given targetValue;
int targetValue = 81;
// Function Call
findX(targetValue);
}
Java
// Java program for
// the above example
import java.util.*;
class GFG{
// Function to find X such
// that it is less than the
// target value and function
// is f(x) = x^2
static void findX(int targetValue)
{
// Initialise start and end
int start = 0, end = targetValue;
int mid = 0, result = 0;
// Loop till start <= end
while (start <= end)
{
// Find the mid
mid = start + (end - start) / 2;
// Check for the left half
if (mid * mid <= targetValue)
{
// Store the result
result = mid;
// Reinitialize the start point
start = mid + 1;
}
// Check for the right half
else
{
end = mid - 1;
}
}
// Print the maximum value of x
// such that x^2 is less than the
// targetValue
System.out.print(result + "\n");
}
// Driver Code
public static void main(String[] args)
{
// Given targetValue;
int targetValue = 81;
// Function call
findX(targetValue);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for
# the above example
# Function to find X such
# that it is less than the
# target value and function
# is f(x) = x ^ 2
def findX(targetValue):
# Initialise start and end
start = 0;
end = targetValue;
mid = 0;
# Loop till start <= end
while (start <= end):
# Find the mid
mid = start + (end - start) // 2;
# Check for the left half
if (mid * mid <= targetValue):
result = mid
start = mid + 1;
# Check for the right half
else:
end = mid - 1;
# Print maximum value of x
# such that x ^ 2 is less than the
# targetValue
print(result);
# Driver Code
if __name__ == '__main__':
# Given targetValue;
targetValue = 81;
# Function Call
findX(targetValue);
# This code is contributed by Rajput-Ji
C#
// C# program for
// the above example
using System;
class GFG{
// Function to find X such
// that it is less than the
// target value and function
// is f(x) = x^2
static void findX(int targetValue)
{
// Initialise start and end
int start = 0, end = targetValue;
int mid = 0, result = 0;
// Loop till start <= end
while (start <= end)
{
// Find the mid
mid = start + (end - start) / 2;
// Check for the left half
if (mid * mid <= targetValue)
{
// Store the result
result = mid;
// Reinitialize the start point
start = mid + 1;
}
// Check for the right half
else
{
end = mid - 1;
}
}
// Print the maximum value of x
// such that x^2 is less than the
// targetValue
Console.Write(result + "\n");
}
// Driver Code
public static void Main(String[] args)
{
// Given targetValue;
int targetValue = 81;
// Function Call
findX(targetValue);
}
}
// This code is contributed by 29AjayKumar
9
上述二进制搜索算法最多需要O(log N)比较才能找到小于或等于目标值的最大值。函数f(x)= x 2的值不需要多次求值。
时间复杂度: O(logN)
辅助空间: O(1)