数的范围Java
二分法找左右端点,找左端点正常写,找右端点mid=l+r+1>>1
因为(l+r)/2只可能等于l,而不可能等于r,所以在找左端点时r只要更新则每次它的r值都
不一样,这就保证了r会一直向着等于l的方向前进,即循环是可以正常结束的;
但在找右端点时mid=(l+r)/2=l是有可能的,如果此时刚好l更新,则在进行下一次循环时l
有可能是不变的,所以我们此时就要对整除2之后的结果向上取整,保证在更新l=mid时,
mid不为l,而是取l的上界,使得l不断向着等于r的方向迈进,即向着使得循环结束的方向
迈进。
Java样例
import java.util.*;
public class Main {
static int n,q;
static int[] nums;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
q = sc .nextInt();
nums = new int[n];
for(int i=0;i<n;i++) {
nums[i]=sc.nextInt();
}
for(int a=0;a<q;a++) {
int x = sc.nextInt();
System.out.println(findLeft(x,0,n-1)+" "+findRight(x,0,n-1));
}
}
public static int findRight(int x, int l, int r) {
while(l < r) {
int mid = l+r+1>>1;
if(nums[mid] > x) r=mid-1;
else if(nums[mid] <= x) l = mid;
}
if(nums[l]==x) return l;
else return -1;
}
public static int findLeft(int x,int l,int r) {
while(l < r) {
int mid = (l+r)/2;
if(nums[mid] < x) l=mid+1;
else if(nums[mid] >= x) r = mid;
}
if(nums[r]==x) return r;
else return -1;
}
}