本文介绍了二分查找算法的原理和实现方法。这是一种高效的搜索算法,通过不断缩小搜索范围,将查找目标与中间元素进行比较,从而快速定位目标元素的位置。二分查找真的是简单但是最容易出错的算法,我们来通过leeetcode的一道题来巩固这个算法。
题目:
来源:leetcode第34题,难度为中等
思路:
看到数组是有序的,瞬间想到二分算法,需要找到两个位置,那么就用两次二分算法,分别找到开始位置和结束位置。
开始位置:
1.定义left在数组最左端,right在数组最右端
2.每次取中间mid,如果中间的值小于目标值,就让left=mid+1,否则就让right=mid,一直循环
3.当left=right的时候,就是结果
4.判断left位置的值是否等于目标值,如果相等,left就是开始位置,用begin记录left,否则,结果不存在,返回[-1,-1]
结束位置
总体来说和开始位置的算法差不多,有一些小区别
1.left此时已经找到开始位置,所以left不用动,让right在数组最右端
2.每次取中间mid,如果中间的值小于等于目标值,就让left=mid,否则就让right=mid-1,一直循环
3.当left=right的时候,就是结果
4.返回数组[begin,right]
代码实现:
class Solution {
public int[] searchRange(int[] nums, int target) {
int left=0,right=nums.length-1,begin=0;
int []ret={-1,-1};
//判断数组是否为空
if(nums.length==0)
return ret;
//找左端点
while(left<right)
{
int mid=left+(right-left)/2;
if(nums[mid]<target)
left=mid+1;
else
right=mid;
}
if(nums[left]!=target)
return ret;
else
begin=left;//标记左端点
//找右端点
right=nums.length-1;
while(left<right)
{
int mid=left+(right-left+1)/2;
if(nums[mid]<=target)
left=mid;
else
right=mid-1;
}
ret[0]=begin;ret[1]=right;
return ret;
}
}
总结:
虽然思想不难,但还是踩了好多坑:
1.判断条件是left<right,而不是left<=right
在left等于right的时候就已经是结果了,此时如果再判断,就会死循环。
2.(right-left)/2和(right-left+1)/2的区别
这两个的区别就是一个在中间偏左,一个在中间偏右,在寻找左端点的时候必须要使用第一种,寻找右端点的时候,必须要使用第二种,否则都会死循环。