Deciding mid in binary search

拟墨画扇 提交于 2020-04-30 11:38:50

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!