问题
I was practising a questions on hackerearth :
https://www.hackerearth.com/practice/algorithms/searching/binary-search/practice-problems/algorithm/monk-and-special-integer-code-monk/
In this question I had written a binary search code where I had used:
int mid=(low+high)/2
My loop got stuck here and so I was getting TLE for some cases. Having realised the problem (that repeatedly low was being chosen) I changed the mid to low +(high-low+1)/2 and with this change whole test cases passed. (Code 1)
I had also done a similar problem where I had used (low+high)/2 and which also passed all the test cases.
My Question is how do we decide how are we gonna choose mid?
PS:These were practise questions and solved now (by me)
Code1
public static boolean subarray(int mid,long x,long[] sum,int[] a){
int n=a.length;
for(int i=0;i<n-mid+1;i++){
if(sum[mid+i-1]-sum[i]+a[i]>x){
return false;
}
}
return true;
}
public static void binarysearch(long[] sum,int [] a,long x){
int low=1;
int high=a.length;
while(low!=high){
int mid=low+ (high-low+1)/2; //passed
//int mid=(low+high)/2; did n't PASS
if(!subarray(mid,x,sum,a)){//if some greater then x
high=mid-1;
}
else{
//if some less then x okay but can go for more
low=mid;
}
}
System.out.println(low);
}
Code2
public static long binarysearch(long[] a,long x,long[] L,long[] R){
//find first index >= x
BufferedOutputStream out=new BufferedOutputStream(System.out);
int low=0;
int high=a.length;
while(low!=high){
int mid=(low+high)/2;
if(a[mid]<x){
low=mid+1;
}
else{
high=mid;
}
}
long ans=L[low]+x-1;
if(low!=0){
ans=L[low]+x-a[low-1]-1;
}
return ans;
}
回答1:
This technique :
low + (high - low) /2
is mainly used to avoid integer overflow.
Since mid is an instance of a numeric type, it has an upper limit on the value that it can hold. It is possible that the sum of low and high could exceed this maximum value, leading to overflow and unpredictable results. This can occur even if low and high are both legal values (i.e. both positive and high >= low).
The expression mid = low + (high - low) / 2 will never overflow for legal values of high and low and will always give the desired result.
Example:
int low = 1170105034
int high = 1347855270
(low + high) / 2 //outputs -888503496
low + (high - low) / 2 //outputs 1258980152
来源:https://stackoverflow.com/questions/50803216/deciding-mid-in-binary-search