一种简单的二分查找思想模型,可以规避细节设置的错误
作者:互联网
二分查找
二分查找也称折半查找(Binary Search),它是一种效率较高(O(logN)的查找方法,前提是数据结构必须先排好序,可以在数据规模的对数时间复杂度内完成查找。但是,二分查找要求线性表具有有随机访问的特点(例如数组),也要求线性表能够根据中间元素的特点推测它两侧元素的性质,以达到缩减问题规模的效果。
二分查找很好理解,但是细节却容易出错。
一种简单的二分查找算法模型
线性表已经排好序,现在目标是设计两个指针l和r使得表划分为两部分,划分结束后的l,r分别指向类分界的两边。
即是说,l=-1,r=num.length
循环进行的条件是:l+1!=r,这样可保证最后结束循环时候,l,r分别再两类中。
当m=l+(r-l)/2处于第一类时候,l=m,第二类时候h=m,具体两个类的建模根据不同问题去建模即可,根据需要返回l或者r的值
一个例题如下
LeetCode Q34
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1,1] 时间复杂度要求(O(logN)
package JavaCode.leetcode.BinarySearch;
public class Q34 {
public static void main(String[] args) {
int[] A={};//根据需要自己写测试的数组即可
int target=5;//目标
int[] ans=searchRange(A,target);
for (int i = 0; i < 2; i++) {
System.out.println(ans[i]);
}
}
public static int[] searchRange(int[] nums, int target) {
int start=findStart(nums, target);
int last=findEnd(nums,target);
int[] A=new int[2];
A[0]=start;A[1]=last;
return A;
}
public static int findStart(int[] nums,int target){
int l=-1,r= nums.length;
while (l+1!=r){
int m=l+(r-l)/2;
if(nums[m]<target){
l=m;
}
else r=m;
}
if(r==nums.length)return -1;
//当数组为空或者target比最大的值更大的时候,返回-1
else if(nums[r]==target) return r ;//存在时返回r
else return -1;//目标不存在时,返回-1
}
public static int findEnd(int[] nums,int target){
int l=-1,r= nums.length;
while (l+1!=r){
int m=l+(r-l)/2;
if(nums[m]<=target){
l=m;
}
else r=m;
}
if (l==-1) return -1;//
else if(nums[l]==target) return l;
else return -1;
}
}
根据上述方法的原理:应该写两个函数,一个将数组分为小于目标和另外的两部分,此时应该返回r,第二个函数返回小于等于目标的部分和另外一部分,此时返回l,应该注意返回时,两个指针l,r都有可能不在数组索引中(数组为空或者目标值比数组最大值更大,或比数组最小值更小,不存在时候都可能出现这样的情况,同时还应该注意目标存在时才返回相应的指针,不存在目标时,返回的会是错误的指针,所以else后面返回的是-1)
标签:二分,return,target,nums,int,规避,查找,数组 来源: https://www.cnblogs.com/njuwxc/p/14638863.html