Leetcode 367. Valid Perfect Square

Problem Explanation

We have to determine whether a given number is a perfect square. A perfect square is a number that can be expressed as the product of an integer with itself. To do this, we could perform a brute force check where we take every number from 1 to the number and multiply it by itself and see if it equals the input number.

However, there is a more efficient way to solve this problem using a binary search algorithm. Instead of checking the every number, we can start from the middle of the number's range, and keep narrowing the range based on whether the middle number's square is more or less than the number.

Solution Approach

The solution uses a binary search algorithm to find if the positive integer num is a perfect square.

In binary search, we start by setting two pointers, here l and r. The l is set to 1 while the r is the num. Now, we keep on checking the middle number m if it's square is greater than or less than num. If it is greater, then all numbers greater than m will also have squares greater than num, so we pull r to m. If it is lesser, then any number lesser than m should have lesser square too, so we push l to m + 1.

We keep on doing this till we reach a number l such that its square equals num. If such a number is found, we return True, else False.

Example Walkthrough

Let's say, num is 9.

So,

Initially, l = 1 and r = 9.

Middle number m = (l + r) / 2 = (1 + 9) / 2 = 5.

5 is not equal to square root of 9 and 5 * 5 > 9. So, we set r = m.

Now, l = 1, r = 5.

Middle number m = (l + r) / 2 = 3.

Now, 3 * 3 = 9. So, we return True.

If we try the same for num = 8, then no perfect square will be found and we will return False.

Python Solution

1
2python
3class Solution:
4    def isPerfectSquare(self, num: int) -> bool:
5        if num < 2:
6            return True
7
8        l, r = 2, num // 2
9
10        while l <= r:
11            x = l + (r - l) // 2
12            squared_val = x * x
13            if squared_val == num:
14                return True
15            if squared_val > num:
16                r = x - 1
17            else:
18                l = x + 1
19
20        return False

Java Solution

1
2java
3class Solution {
4    public boolean isPerfectSquare(int num) {
5        if (num < 2) return true;
6
7        long l = 2;
8        long r = num / 2;
9
10        while (l <= r) {
11            long mid = l + (r - l) / 2;
12            long guessSquared = mid * mid;
13            if (guessSquared == num) {
14                return true;
15            }
16            if (guessSquared > num) {
17                r = mid - 1;
18            } else {
19                l = mid + 1;
20            }
21        }
22
23        return false;
24    }
25}

JavaScript Solution

1
2javascript
3var isPerfectSquare = function(num) {
4    if (num < 2) return true;
5
6    let l = 2;
7    let r = num / 2;
8
9    while (l <= r) {
10        const mid = Math.floor(l + (r - l) / 2);
11        const guessedSquare = mid * mid;
12
13        if (guessedSquare === num) return true;
14
15        if (guessedSquare > num) {
16            r = mid - 1;
17        } else {
18            l = mid + 1;
19        }
20    }
21
22    return false;
23};

C++ Solution

1
2cpp
3class Solution {
4public:
5    bool isPerfectSquare(int num) {
6        if (num < 2) return true;
7
8        long l = 2;
9        long r = num / 2;
10
11        while (l <= r) {
12            long mid = l + (r - l) / 2;
13            long guessSquared = mid * mid;
14            if (guessSquared == num) {
15                return true;
16            }
17            if (guessSquared > num) {
18                r = mid - 1;
19            } else {
20                l = mid + 1;
21            }
22        }
23
24        return false;
25    }
26};

C# Solution

1
2csharp
3public class Solution {
4    public bool IsPerfectSquare(int num) {
5        if (num < 2) return true;
6
7        long l = 2;
8        long r = num / 2;
9
10        while (l <= r) {
11            long mid = l + (r - l) / 2;
12            long guessSquared = mid * mid;
13            if (guessSquared == num) {
14                return true;
15            }
16            if (guessSquared > num) {
17                r = mid - 1;
18            } else {
19                l = mid + 1;
20            }
21        }
22
23        return false;
24    }
25}

The binary search algorithm provides a time efficient solution for this problem, thanks to its logarithmic time complexity. If you analyze the time complexity of this algorithm, you'll find it to be O(log n).

Here, the binary search algorithm starts from the middle of the number's range. After each comparison, binary search eliminates half of the remaining possibilities. With every unsuccessful comparison, binary search cuts the problem size by half until it narrows down to the exact or no number. This makes the binary search a highly efficient search algorithm.

Overall, this problem teaches us how an efficient algorithm can be constructed utilizing binary search to check if a number is a perfect square or not. We learned to construct this solution in multiple languages - Python, Java, JavaScript, C++, and C#. The logic and implementation stays the same across languages. We just have to take care of minor differences between languages, such as type checking, integer/float division, and handling of variables.

With a good understanding of binary search and logic building, such problems can be solved in an efficient manner, making your algorithm suitable for larger inputs as well.

The solutions provided here can be utilized in multiple use cases in the programming world. For example, developing games, data analysis, and many other applications where we need to check if a number is a perfect square or not. The solutions can be further optimized according to the use case and the platform being used. But they provide a good foundation for anyone to understand the solution and its underlying concepts.

Remember, problem solving is a skill that gets better with practice. So take up problems, break them down, understand the logic, and draft its solutions. And languages shouldn't become a barrier in your path, so keep exploring more and more languages and expand your skill set.


Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.


TA 👨‍🏫