什么是二分查找算法?
二分搜索算法用于找到需要最大化或最小化某个定义函数f(x)的特定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.
如何使用二分搜索解决问题:
如果函数是
任务是找到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
Javascript
9
上述二分查找算法最多需要O(log N)次比较才能找到小于或等于目标值的最大值。并且函数f(x) = x 2的值不需要计算多次。
时间复杂度: O(logN)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。