Given a positive integer num, return true if num is a perfect square or false otherwise.
A perfect square is an integer that is the square of an integer. In other words, it is the product of some integer with itself.
You must not use any built-in library function, such as sqrt.
Example 1:
Input: num = 16 Output: true Explanation: We return true because 4 * 4 = 16 and 4 is an integer.
Example 2:
Input: num = 14 Output: false Explanation: We return false because 3.742 * 3.742 = 14 and 3.742 is not an integer.
Constraints:
1 <= num <= 231 - 1When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The problem asks us to determine if a given number is a perfect square. The brute force approach involves checking every possible whole number to see if its square equals the given number.
Here's how the algorithm would work step-by-step:
def is_valid_perfect_square_brute_force(number):
current_number = 1
while True:
square = current_number * current_number
# If the square equals the number, it's a perfect square
if square == number:
return True
# If the square is larger, the number isn't a perfect square
if square > number:
return False
# Increment the current number to check the next square
current_number += 1
Instead of checking every possible number, we can use a more efficient search strategy. This strategy eliminates large portions of potential numbers quickly, focusing only on the most promising candidates. By doing this, we avoid unnecessary calculations and find the answer much faster.
Here's how the algorithm would work step-by-step:
def is_perfect_square(number):
if number < 0:
return False
low_range = 0
high_range = number
while low_range <= high_range:
mid_range = (low_range + high_range) // 2
squared_value = mid_range * mid_range
if squared_value == number:
return True
elif squared_value < number:
# The square root must be larger, so adjust the lower bound.
low_range = mid_range + 1
else:
# The square root must be smaller, so adjust the upper bound.
high_range = mid_range - 1
# If the loop finishes without finding a square root,
# the number is not a perfect square.
return False| Case | How to Handle |
|---|---|
| Input is 0 | Return true since 0 * 0 = 0 and 0 is a perfect square. |
| Input is 1 | Return true since 1 * 1 = 1 and 1 is a perfect square. |
| Input is a large perfect square close to the maximum integer value (Integer.MAX_VALUE) | Use long for calculations to prevent potential integer overflow during the square root calculation or squaring the mid value. |
| Input is a number slightly larger than a perfect square | The binary search should correctly narrow down the search space and return false. |
| Input is a negative number | Return false, as perfect squares are non-negative. |
| Input is Integer.MAX_VALUE | Utilize long to prevent overflow, calculate the square root or use binary search until the middle element surpasses the boundary |
| Input is a perfect square represented by the maximum value of a smaller data type (e.g., Short.MAX_VALUE) | The algorithm should handle the input as a perfect square without any data type limitation issues if we are using Integer or Long. |
| Algorithm using Math.sqrt() might have floating-point precision issues. | Compare the square of the integer part of the square root against the input to avoid floating-point inaccuracies. |