LeetCode704.二分查找(Java)
题解
在[0,nums.length-1]的范围内对nums顺序数组进行搜索;
设置起始区间[L,R],其中L=0,R=nums.length;
取M=(L+R)/2,即取区间中位数进行判断;
如果target>nums[M],说明[L,M]范围内都是比target小的数,下一步应该在[M+1,r]范围内查找,因此将L更新,即令L=M+1;
如果target<nums[M],说明[M,R]范围内都是比target大的数,下一步应该在[L,M-1]范围内查找,因此将R更新,即令R=M-1;
如果target == nums[M],搜索结束,循环结束条件是L>=R,因此,令L=R=M即可满足结束条件;
结束循环后,因为L一直小于R,所以一定有M<=nums.length-2(极限情况下有L<R == nums.length-1,此时M=(L+R)/2 == nums.length-2),L的增长是在M的基础上,所以L不会超过数组长度;
又如果循环到了L=0,R=1的情况,则M=0,同时有nums[M]>target,则R=M-1==-1,L仍然不会超过数组范围下界,
综上一定有L∈[0,nums.length-1],不用担心会超出界限,因此可以直接返回nums[L]==target?L:-1
代码
public int search_704(int[] nums,int target){
/**
*算法步骤
*在[0,nums.length-1]的范围内对nums顺序数组进行搜索
* 设置起始区间[L,R],其中L=0,R=nums.length
* 取M=(L+R)/2,即取区间中位数进行判断
* 如果target>nums[M],说明[L,M]范围内都是比target小的数,下一步应该在[M+1,r]范围内查找,因此将L更新,即令L=M+1;
* 如果target<nums[M],说明[M,R]范围内都是比target大的数,下一步应该在[L,M-1]范围内查找,因此将R更新,即令R=M-1;
* 如果target==nums[M],搜索结束,循环结束条件是L>=R,因此,令L=R=M即可满足结束条件
* 结束循环后,因为L一直小于R,所以一定有M<=nums.length-2(极限情况下有L<R==nums.length-1,此时M=(L+R)/2==nums.length-2),L的增长是在M的基础上,所以L不会超过数组长度
* 又如果循环到了L=0,R=1的情况,则M=0,同时有nums[M]>target,则R=M-1==-1,L仍然不会超过数组范围下界,
* 综上一定有L∈[0,nums.length-1],不用担心会超出界限,因此可以直接返回nums[L]==target?L:-1
* */
int l=0;
int r=nums.length-1;
int m;
while(l<r){
m=(l+r)/2;
if(target>nums[m])l=m+1;
else if(target<nums[m])r=m-1;
else l=r=m;
}
return nums[l]==target?l:-1;
}