Unbounded Binary Search Example (Find the point where a monotonically increasing function becomes positive first time)

23 Feb, 2022
Given a function ‘int f(unsigned int x)’ which takes a non-negative integer ‘x’ as input and returns an integer as output. The function is monotonically increasing with respect to the value of x, i.e., the value of f(x+1) is greater than f(x) for every input x. Find the value ‘n’ where f() becomes positive for the first time. Since f() is monotonically increasing, values of f(n+1), f(n+2),... must be positive and values of f(n-2), f(n-3), ... must be negative. Find n in O(logn) time, you may assume that f(x) can be evaluated in O(1) time for any input x. 
A simple solution is to start from i equals to 0 and one by one calculate the value of f(i) for 1, 2, 3, 4 ... etc until we find a positive f(i). This works but takes O(n) time.Can we apply Binary Search to find n in O(Logn) time? We can’t directly apply Binary Search as we don’t have an upper limit or high index. The idea is to do repeated doubling until we find a positive value, i.e., check values of f() for following values until f(i) becomes positive.
  f(0) 
  f(1)
  f(2)
  f(4)
  f(8)
  f(16)
  f(32)
  ....
  ....
  f(high)
Let 'high' be the value of i when f() becomes positive for first time.
Can we apply Binary Search to find n after finding ‘high’? We can apply Binary Search now, we can use ‘high/2’ as low and ‘high’ as high indexes in binary search. The result n must lie between ‘high/2’ and ‘high’.The number of steps for finding ‘high’ is O(Logn). So we can find ‘high’ in O(Logn) time. What about the time taken by Binary Search between high/2 and high? The value of ‘high’ must be less than 2*n. The number of elements between high/2 and high must be O(n). Therefore, the time complexity of Binary Search is O(Logn) and the overall time complexity is 2*O(Logn) which is O(Logn).  
C++
C
Java
Python3
C#
PHP
Javascript
// C++ code for binary search#include<bits/stdc++.h>using namespace std; int binarySearch(int low, int high); // prototype // Let's take an example function// as f(x) = x^2 - 10*x - 20 Note that// f(x) can be any monotonically increasing functionint f(int x) { return (x*x - 10*x - 20); } // Returns the value x where above// function f() becomes positive// first time.int findFirstPositive(){    // When first value itself is positive    if (f(0) > 0)        return 0;     // Find 'high' for binary search by repeated doubling    int i = 1;    while (f(i) <= 0)        i = i*2;     // Call binary search    return binarySearch(i/2, i);} // Searches first positive value// of f(i) where low <= i <= highint binarySearch(int low, int high){    if (high >= low)    {        int mid = low + (high - low)/2; /* mid = (low + high)/2 */         // If f(mid) is greater than 0 and        // one of the following two        // conditions is true:        // a) mid is equal to low        // b) f(mid-1) is negative        if (f(mid) > 0 && (mid == low || f(mid-1) <= 0))            return mid;         // If f(mid) is smaller than or equal to 0        if (f(mid) <= 0)            return binarySearch((mid + 1), high);        else // f(mid) > 0            return binarySearch(low, (mid -1));    }     /* Return -1 if there is no    positive value in given range */    return -1;} /* Driver code */int main(){    cout<<"The value n where f() becomes" <<        "positive first is "<< findFirstPositive();    return 0;} // This code is contributed by rathbhupendra
#include <stdio.h>int binarySearch(int low, int high); // prototype // Let's take an example function as f(x) = x^2 - 10*x - 20// Note that f(x) can be any monotonically increasing functionint f(int x) { return (x*x - 10*x - 20); } // Returns the value x where above function f() becomes positive// first time.int findFirstPositive(){    // When first value itself is positive    if (f(0) > 0)        return 0;     // Find 'high' for binary search by repeated doubling    int i = 1;    while (f(i) <= 0)        i = i*2;     //  Call binary search    return binarySearch(i/2, i);} // Searches first positive value of f(i) where low <= i <= highint binarySearch(int low, int high){    if (high >= low)    {        int mid = low + (high - low)/2; /* mid = (low + high)/2 */         // If f(mid) is greater than 0 and one of the following two        // conditions is true:        // a) mid is equal to low        // b) f(mid-1) is negative        if (f(mid) > 0 && (mid == low || f(mid-1) <= 0))            return mid;         // If f(mid) is smaller than or equal to 0        if (f(mid) <= 0)            return binarySearch((mid + 1), high);        else // f(mid) > 0            return binarySearch(low, (mid -1));    }     /* Return -1 if there is no positive value in given range */    return -1;} /* Driver program to check above functions */int main(){    printf("The value n where f() becomes positive first is %d",           findFirstPositive());    return 0;}
// Java program for Binary Searchimport java.util.*; class Binary{    public static int f(int x)    { return (x*x - 10*x - 20); }     // Returns the value x where above    // function f() becomes positive    // first time.    public static int findFirstPositive()    {        // When first value itself is positive        if (f(0) > 0)            return 0;         // Find 'high' for binary search        // by repeated doubling        int i = 1;        while (f(i) <= 0)            i = i * 2;         // Call binary search        return binarySearch(i / 2, i);    }     // Searches first positive value of    // f(i) where low <= i <= high    public static int binarySearch(int low, int high)    {        if (high >= low)        {              /* mid = (low + high)/2 */            int mid = low + (high - low)/2;             // If f(mid) is greater than 0 and            // one of the following two            // conditions is true:            // a) mid is equal to low            // b) f(mid-1) is negative            if (f(mid) > 0 && (mid == low || f(mid-1) <= 0))                return mid;             // If f(mid) is smaller than or equal to 0            if (f(mid) <= 0)                return binarySearch((mid + 1), high);            else // f(mid) > 0                return binarySearch(low, (mid -1));        }         /* Return -1 if there is no positive        value in given range */        return -1;    }         // driver code    public static void main(String[] args)    {        System.out.print ("The value n where f() "+                         "becomes positive first is "+                         findFirstPositive());    }} // This code is contributed by rishabh_jain
# Python3 program for Unbound Binary search. # Let's take an example function as# f(x) = x^2 - 10*x - 20# Note that f(x) can be any monotonically# increasing functiondef f(x):    return (x * x - 10 * x - 20) # Returns the value x where above function# f() becomes positive first time.def findFirstPositive() :         # When first value itself is positive    if (f(0) > 0):        return 0     # Find 'high' for binary search    # by repeated doubling    i = 1    while (f(i) <= 0) :        i = i * 2     # Call binary search    return binarySearch(i/2, i) # Searches first positive value of# f(i) where low <= i <= highdef binarySearch(low, high):    if (high >= low) :                 # mid = (low + high)/2        mid = low + (high - low)/2;          # If f(mid) is greater than 0        # and one of the following two        # conditions is true:        # a) mid is equal to low        # b) f(mid-1) is negative        if (f(mid) > 0 and (mid == low or f(mid-1) <= 0)) :            return mid;         # If f(mid) is smaller than or equal to 0        if (f(mid) <= 0) :            return binarySearch((mid + 1), high)        else : # f(mid) > 0            return binarySearch(low, (mid -1))         # Return -1 if there is no positive    # value in given range    return -1; # Driver Codeprint ("The value n where f() becomes "+      "positive first is ", findFirstPositive()); # This code is contributed by rishabh_jain
// C# program for Binary Searchusing System; class Binary{    public static int f(int x)    {        return (x*x - 10*x - 20);    }     // Returns the value x where above    // function f() becomes positive    // first time.    public static int findFirstPositive()    {        // When first value itself is positive        if (f(0) > 0)            return 0;         // Find 'high' for binary search        // by repeated doubling        int i = 1;        while (f(i) <= 0)            i = i * 2;         // Call binary search        return binarySearch(i / 2, i);    }     // Searches first positive value of    // f(i) where low <= i <= high    public static int binarySearch(int low, int high)    {        if (high >= low)        {            /* mid = (low + high)/2 */            int mid = low + (high - low)/2;             // If f(mid) is greater than 0 and            // one of the following two            // conditions is true:            // a) mid is equal to low            // b) f(mid-1) is negative            if (f(mid) > 0 && (mid == low ||                             f(mid-1) <= 0))                return mid;             // If f(mid) is smaller than or equal to 0            if (f(mid) <= 0)                return binarySearch((mid + 1), high);            else                             // f(mid) > 0                return binarySearch(low, (mid -1));        }         /* Return -1 if there is no positive        value in given range */        return -1;    }         // Driver code    public static void Main()    {       Console.Write ("The value n where f() " +                      "becomes positive first is " +                       findFirstPositive());    }} // This code is contributed by nitin mittal
<?php// PHP program for Binary Search // Let's take an example function// as f(x) = x^2 - 10*x - 20// Note that f(x) can be any// monotonically increasing functionfunction f($x){    return ($x * $x - 10 * $x - 20);} // Returns the value x where above// function f() becomes positive// first time.function findFirstPositive(){    // When first value    // itself is positive    if (f(0) > 0)        return 0;     // Find 'high' for binary    // search by repeated doubling    $i = 1;    while (f($i) <= 0)        $i = $i * 2;     // Call binary search    return binarySearch(intval($i / 2), $i);} // Searches first positive value// of f(i) where low <= i <= highfunction binarySearch($low, $high){    if ($high >= $low)    {        /* mid = (low + high)/2 */        $mid = $low + intval(($high -                              $low) / 2);         // If f(mid) is greater than 0        // and one of the following two        // conditions is true:        // a) mid is equal to low        // b) f(mid-1) is negative        if (f($mid) > 0 && ($mid == $low ||                          f($mid - 1) <= 0))            return $mid;         // If f(mid) is smaller        // than or equal to 0        if (f($mid) <= 0)            return binarySearch(($mid + 1), $high);        else // f(mid) > 0            return binarySearch($low, ($mid - 1));    }     /* Return -1 if there is no    positive value in given range */    return -1;} // Driver Codeecho "The value n where f() becomes ".                 "positive first is ".                 findFirstPositive() ; // This code is contributed by Sam007?>
<script>    // Javascript program for Binary Search         function f(x)    {        return (x*x - 10*x - 20);    }       // Returns the value x where above    // function f() becomes positive    // first time.    function findFirstPositive()    {        // When first value itself is positive        if (f(0) > 0)            return 0;           // Find 'high' for binary search        // by repeated doubling        let i = 1;        while (f(i) <= 0)            i = i * 2;           // Call binary search        return binarySearch(parseInt(i / 2, 10), i);    }       // Searches first positive value of    // f(i) where low <= i <= high    function binarySearch(low, high)    {        if (high >= low)        {            /* mid = (low + high)/2 */            let mid = low + parseInt((high - low)/2, 10);               // If f(mid) is greater than 0 and            // one of the following two            // conditions is true:            // a) mid is equal to low            // b) f(mid-1) is negative            if (f(mid) > 0 && (mid == low ||                             f(mid-1) <= 0))                return mid;               // If f(mid) is smaller than or equal to 0            if (f(mid) <= 0)                return binarySearch((mid + 1), high);            else                               // f(mid) > 0                return binarySearch(low, (mid -1));        }           /* Return -1 if there is no positive        value in given range */        return -1;    }         document.write ("The value n where f() " +                      "becomes positive first is " +                       findFirstPositive()); </script>
Output : 
The value n where f() becomes positive first is 12
 
nitin mittal
Sam007
rathbhupendra
vaibhavrabadiya117
simmytarika5
Binary Search
Divide and Conquer
Searching
Searching
Divide and Conquer
Binary Search
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.