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++
// 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 |
C
#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; } |
Java
// 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 |
Python3
# 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 |
C#
// 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 |
PHP
<?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 ?> |
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.