二分法,这一看似简单却又充满哲理的算法,犹如一道精巧的数学之门,带领我们在问题的迷雾中找到清晰的道路。它的名字虽简单,却深藏着智慧的光辉。在科学的浩瀚星空中,二分法如一颗璀璨的星辰,指引着我们如何高效地寻找答案。本文将带领大家走进二分法的世界,探讨它的原理、应用及其在各种问题中的深远影响。
二分法,顾名思义,是将一个问题或区间不断地分成两个部分,逐步逼近目标答案。最常见的应用是求解有序数列中的某个元素,或者求解某个函数的零点。 其基本思路如下:
这种“分而治之”的策略,极大地提高了搜索效率,尤其在处理大规模数据时,具有显著的优势。
下面我们将结合具体题型进行二分法的使用与讲解。
此题较为简单,查找目标值,直接遍历即可,且数据量不大,应该不会超时,不再给出示例代码。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;//确定左右边界
//由于两个指针相交时还未判断是否等于target,因此需要取等号
while(left<=right)
{
int mid=(left+right)/2;
if(nums[mid]>target)
{
right=mid-1;
}//更新右边界
else if(nums[mid]<target)
{
left=mid+1;
}//更新左区间
else
{
return mid;
}
}
return -1;
}
};问题:时间复杂度的要求和数组的二段性已经很明显的提示我们需要使用二分法,可是二分法我们只尝试过查找单个target,面对一连串的target,我们又该如何处理呢?
虽然我们要查找的target是一串区间,但是数组仍满足二段性,在target起始区间的左侧,所有元素均小于target,而在target结束区间的右侧,所有元素均大于target。
因此,我们使用两次二分,分别查找该区间的左右边界即可,具体步骤如下:


class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size()==0)
{
return {-1,-1};
}
int left=0,right=nums.size()-1;
int begin=0;
//查找左边界
while(left<right)
{
int mid=left+(right-left)/2;
if(nums[mid]<target)
{
left=mid+1;
}//更新left
else
{
right=mid;
}//更新right
}
if(nums[left]!=target)
{
return {-1,-1};
}//若左边界未查找成功,说明不存在target,直接返回
begin=left;//查找成功,更新左边界
//查找右边界
right=nums.size()-1;//将right恢复为初始状态
while(left<right)
{
int mid=left+(right-left+1)/2;
if(nums[mid]==target)
{
left=mid;
}//更新left
else
{
right=mid-1;
}//更新right
}
return {begin,right};
}
};我们可假设目标值为target,那么该题所有答案都在[0,n]的这个数组内。
且[0,target]内,所有元素的平方和均小于x,[target,x]内,所有元素的平方和均大于x,即满足二段性,因此可考虑使用二分法进行解决。 具体步骤如下:
class Solution {
public:
int mySqrt(int x) {
int left=1,right=x;
if(x==0)
{
return 0;
}
while(left<right)
{
long long mid=left+(right-left+1)/2;//防止越界
if(mid*mid<=x)
{
left=mid;
}//更新left
else
{
right=mid-1;
}//更新right
}
return left;
}
};由上述分析不难发现可是用二分法。
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int left=1,right=arr.size()-2;//峰顶元素即为最大值
while(left<right)
{
int mid=left+(right-left+1)/2;
if(arr[mid]>arr[mid-1])
{
left=mid;
}//mid在上升区间内
else
{
right=mid-1;
}
}
return left;
}
};尽管二分法在许多情况下都表现出极高的效率,但它也并非万能。在应用二分法时,要求数据必须是有序的,否则无法直接应用。此外,二分法在处理某些特殊类型的问题时,可能需要额外的技巧或调整。例如,求解无序数据中的元素时,二分法并不能直接使用,需要先进行排序或采取其他的算法。
二分法的时间复杂度为 O(log n),这使得它在处理大规模数据时,具有非常高的效率。在最坏的情况下,每一步都将问题规模缩小一半,从而大大减少了运算的次数。与线性搜索相比,二分法能大幅度提高搜索效率,尤其是在数据量极大的情况下。
二分法作为一种简单而高效的算法,已经成为计算机科学与数学中不可或缺的一部分。它不仅仅是一个算法工具,更是我们思考问题、解决问题的哲学。在这条“二分之间”的道路上,我们不仅找到了问题的解答,也探索到了求解问题的一种智慧。它教会我们,在复杂问题面前,不妨将问题拆解,逐步攻克,最终发现通往答案的光明之路。
本篇关于二分法的介绍就暂告一段落啦,希望能对大家的学习产生帮助,欢迎各位佬前来支持斧正!!!