0% found this document useful (0 votes)
18 views8 pages

Predicate Binary Search

This document explains how to use binary search to efficiently find the square root of a perfect square number X, contrasting it with a brute-force approach that has a time complexity of O(X). By applying binary search, the time complexity is reduced to O(log X), making it suitable for larger values of X. The document provides a detailed walkthrough of the binary search process with examples and code implementation.

Uploaded by

nopedo3559
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views8 pages

Predicate Binary Search

This document explains how to use binary search to efficiently find the square root of a perfect square number X, contrasting it with a brute-force approach that has a time complexity of O(X). By applying binary search, the time complexity is reduced to O(log X), making it suitable for larger values of X. The document provides a detailed walkthrough of the binary search process with examples and code implementation.

Uploaded by

nopedo3559
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Binary search is a powerful algorithm, widely used to solve problems

efficiently by narrowing down the search space. In this lesson, we will use
binary search to find the square root of a perfect square number. We will
break down the process into smaller, digestible parts to help you understand
the intuition behind it.

Introduction: Problem Statement

You are given a perfect square number X, and the goal is to find its square
root.

A brute-force approach would be to start from 1 and check each number until
we find the one whose square equals X. For example:

int num = -1;


for (int i = 0; i <= X; i++) {
if (i * i == X) {
num = i;
break;
}
}

This brute-force approach has a time complexity of O(X), which can be quite
slow for large values of X.

As we know that num*num==X, so there is no need to iterate till X, we can


iterate till a specific condition (i*i<=X) is reached.
So the above problem can be solved in O(sqrt(X)) time complexity.

int num = -1;


for (int i = 0; i*i <= X; i++) {
if (i * i == X) {
num = i;
break;
}
}

Optimizing the Approach: Condition to Stop Early


Instead of checking every number from 1 to X, we can optimize the solution.
We know that we are looking for the largest number num such that:

For example, if X = 25, then the numbers 1, 2, 3, 4, and 5 satisfy the condition
num * num <= X. The largest number satisfying this condition will be the
square root of X.

Before we proceed let’s talk about predicate functions.

A predicate function is a function that returns a true or false value. It is often


used to check if a certain condition holds for a given input. In this case, our
predicate function will check whether num * num <= X.

For example :

bool isLessThanOrEqual(int num, int X) {

if(num*num<=X) return true;

else return false;

}
Applying Binary Search

The idea is to use binary search to find the largest num such that num *
num <= X.

Initial Range:

●​ lo = 0
●​ hi = X

We will update lo and hi based on the value of mid during each iteration.
Here’s a detailed walkthrough of the binary search process.

Example: Finding the Square Root of X = 36

Step 1: Initialize

●​ lo = 0
●​ hi = 36

Step 2: First Iteration

●​ mid = (lo + hi) / 2 = (0 + 36) / 2 = 18


●​ mid * mid = 18 * 18 = 324 > 36

Since mid * mid > X, the square root must lie between lo = 0 and hi = mid - 1
= 17.

As mid = 18, since 18*18 is greater than 36, so all the numbers from 18 to 36,
will have their square greater than 36.

lo hi mid mid * mid Action

0 36 18 324 mid * mid > X, so update hi = 17


Step 3: Second Iteration

●​ lo = 0, hi = 17
●​ mid = (lo + hi) / 2 = (0 + 17) / 2 = 8
●​ mid * mid = 8 * 8 = 64 > 36

Since mid * mid > X, update hi = mid - 1 = 7.

lo hi mid mid * Action


mid

0 17 8 64 mid * mid > X, so update hi = 7

Step 4: Third Iteration

●​ lo = 0, hi = 7
●​ mid = (lo + hi) / 2 = (0 + 7) / 2 = 3
●​ mid * mid = 3 * 3 = 9 <= 36

Since mid * mid <= X, update the answer to 3, and continue the search in the
range lo = mid + 1 = 4 to hi = 7.

lo hi mid mid * mid Action

0 7 3 9 mid * mid <= X, update answer = 3

Step 5: Fourth Iteration

●​ lo = 4, hi = 7
●​ mid = (lo + hi) / 2 = (4 + 7) / 2 = 5
●​ mid * mid = 5 * 5 = 25 <= 36

Since mid * mid <= X, update the answer to 5, and continue searching
between lo = mid + 1 = 6 and hi = 7.

lo hi mid mid * mid Action

4 7 5 25 mid * mid <= X, update answer = 5

Step 6: Fifth Iteration

●​ lo = 6, hi = 7
●​ mid = (lo + hi) / 2 = (6 + 7) / 2 = 6
●​ mid * mid = 6 * 6 = 36 <= 36

Since mid * mid == X, update the answer to 6, and continue searching


between lo = mid + 1 = 7 and hi = 7.

lo hi mid mid * mid Action

6 7 6 36 mid * mid == X, update


answer = 6

Step 7: Sixth Iteration

●​ lo = 7, hi = 7
●​ mid = (lo + hi) / 2 = 7
●​ mid * mid = 7 * 7 = 49 > 36
Since mid * mid > X, update hi = mid - 1 = 6.

lo hi mid mid * mid Action

7 7 7 49 mid * mid > X, so update


hi = 6

At this point, lo = 7 and hi = 6, so the binary search terminates.

Final Answer

The last value of answer is 6, which is the correct square root of X = 36.

Square root of 36=6​

Code :

bool good(int num, int x){

if(num*num<=x){

return true;

return false;

int main(){

int lo=0, hi=x;

int ans=-1;
while(lo<=hi){

int mid=(lo+hi)/2;

if(good(mid,x)){

ans=mid;

lo=mid+1;

else{

hi = mid-1;

cout<<ans<<endl;

Time Complexity

The time complexity of binary search is O(log X), which is far more efficient
than the brute-force approach (O(X)). This makes binary search ideal for large
numbers.

Learnings :
Binary search is not specific to arrays. If you are able to find patterns in
monotonic predicate functions, they you can apply binary search on it.​
If you are able to find that the function is monotonic, you can apply binary
search on it.
Some times, you don’t apply binary search on answer exactly, you have to
apply on different argument, from which you can get answer.​
More problems : ​
https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/descri
ption/
https://leetcode.com/problems/minimum-number-of-days-to-make-m-bouquets
/description/
https://leetcode.com/problems/sum-of-mutated-array-closest-to-target/descript
ion/

You might also like