Unbounded Binary Search Example (Find the point where a monotonically increasing function becomes positive first time)
Last Updated :
12 Oct, 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++
#include<bits/stdc++.h>
using namespace std;
int binarySearch( int low, int high);
int f( int x) { return (x*x - 10*x - 20); }
int findFirstPositive()
{
if (f(0) > 0)
return 0;
int i = 1;
while (f(i) <= 0)
i = i*2;
return binarySearch(i/2, i);
}
int binarySearch( int low, int high)
{
if (high >= low)
{
int mid = low + (high - low)/2;
if (f(mid) > 0 && (mid == low || f(mid-1) <= 0))
return mid;
if (f(mid) <= 0)
return binarySearch((mid + 1), high);
else
return binarySearch(low, (mid -1));
}
return -1;
}
int main()
{
cout<< "The value n where f() becomes" <<
"positive first is " << findFirstPositive();
return 0;
}
|
C
#include <stdio.h>
int binarySearch( int low, int high);
int f( int x) { return (x*x - 10*x - 20); }
int findFirstPositive()
{
if (f(0) > 0)
return 0;
int i = 1;
while (f(i) <= 0)
i = i*2;
return binarySearch(i/2, i);
}
int binarySearch( int low, int high)
{
if (high >= low)
{
int mid = low + (high - low)/2;
if (f(mid) > 0 && (mid == low || f(mid-1) <= 0))
return mid;
if (f(mid) <= 0)
return binarySearch((mid + 1), high);
else
return binarySearch(low, (mid -1));
}
return -1;
}
int main()
{
printf ( "The value n where f() becomes positive first is %d" ,
findFirstPositive());
return 0;
}
|
Java
import java.util.*;
class Binary
{
public static int f( int x)
{ return (x*x - 10 *x - 20 ); }
public static int findFirstPositive()
{
if (f( 0 ) > 0 )
return 0 ;
int i = 1 ;
while (f(i) <= 0 )
i = i * 2 ;
return binarySearch(i / 2 , i);
}
public static int binarySearch( int low, int high)
{
if (high >= low)
{
int mid = low + (high - low)/ 2 ;
if (f(mid) > 0 && (mid == low || f(mid- 1 ) <= 0 ))
return mid;
if (f(mid) <= 0 )
return binarySearch((mid + 1 ), high);
else
return binarySearch(low, (mid - 1 ));
}
return - 1 ;
}
public static void main(String[] args)
{
System.out.print ( "The value n where f() " +
"becomes positive first is " +
findFirstPositive());
}
}
|
Python3
def f(x):
return (x * x - 10 * x - 20 )
def findFirstPositive() :
if (f( 0 ) > 0 ):
return 0
i = 1
while (f(i) < = 0 ) :
i = i * 2
return binarySearch(i / 2 , i)
def binarySearch(low, high):
if (high > = low) :
mid = low + (high - low) / 2 ;
if (f(mid) > 0 and (mid = = low or f(mid - 1 ) < = 0 )) :
return mid;
if (f(mid) < = 0 ) :
return binarySearch((mid + 1 ), high)
else :
return binarySearch(low, (mid - 1 ))
return - 1 ;
print ( "The value n where f() becomes " +
"positive first is " , findFirstPositive());
|
C#
using System;
class Binary
{
public static int f( int x)
{
return (x*x - 10*x - 20);
}
public static int findFirstPositive()
{
if (f(0) > 0)
return 0;
int i = 1;
while (f(i) <= 0)
i = i * 2;
return binarySearch(i / 2, i);
}
public static int binarySearch( int low, int high)
{
if (high >= low)
{
int mid = low + (high - low)/2;
if (f(mid) > 0 && (mid == low ||
f(mid-1) <= 0))
return mid;
if (f(mid) <= 0)
return binarySearch((mid + 1), high);
else
return binarySearch(low, (mid -1));
}
return -1;
}
public static void Main()
{
Console.Write ( "The value n where f() " +
"becomes positive first is " +
findFirstPositive());
}
}
|
PHP
<?php
function f( $x )
{
return ( $x * $x - 10 * $x - 20);
}
function findFirstPositive()
{
if (f(0) > 0)
return 0;
$i = 1;
while (f( $i ) <= 0)
$i = $i * 2;
return binarySearch( intval ( $i / 2), $i );
}
function binarySearch( $low , $high )
{
if ( $high >= $low )
{
$mid = $low + intval (( $high -
$low ) / 2);
if (f( $mid ) > 0 && ( $mid == $low ||
f( $mid - 1) <= 0))
return $mid ;
if (f( $mid ) <= 0)
return binarySearch(( $mid + 1), $high );
else
return binarySearch( $low , ( $mid - 1));
}
return -1;
}
echo "The value n where f() becomes " .
"positive first is " .
findFirstPositive() ;
?>
|
Javascript
<script>
function f(x)
{
return (x*x - 10*x - 20);
}
function findFirstPositive()
{
if (f(0) > 0)
return 0;
let i = 1;
while (f(i) <= 0)
i = i * 2;
return binarySearch(parseInt(i / 2, 10), i);
}
function binarySearch(low, high)
{
if (high >= low)
{
let mid = low + parseInt((high - low)/2, 10);
if (f(mid) > 0 && (mid == low ||
f(mid-1) <= 0))
return mid;
if (f(mid) <= 0)
return binarySearch((mid + 1), high);
else
return binarySearch(low, (mid -1));
}
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
Time Complexity: O(logn)
Auxiliary Space: O(logn)
Share your thoughts in the comments
Please Login to comment...