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

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 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 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’.

Number of steps for finding ‘high’ is O(Logn). So we can find ‘high’ in O(Logn) time. What about 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, time complexity of Binary Search is O(Logn) and overall time complexity is 2*O(Logn) which is O(Logn).

C++



filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 monotonocally increasing function 
int 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 <= high 
int 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

chevron_right


C

filter_none

edit
close

play_arrow

link
brightness_4
code

#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 monotonocally increasing function
int 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 <= high
int 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for Binary Search
import 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 monotonocally 
# increasing function
def 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 <= high
def 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 Code
print ("The value n where f() becomes "+
      "positive first is ", findFirstPositive());
  
# This code is contributed by rishabh_jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for Binary Search
using 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

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?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 
// monotonocally increasing function
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
    $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 <= high
function 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 Code
echo "The value n where f() becomes "
                 "positive first is "
                 findFirstPositive() ;
  
// This code is contributed by Sam007
?>

chevron_right



Output :

The value n where f() becomes positive first is 12

Related Article:
Exponential Search

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up