Given a positive integer num
, determine whether num
is a perfect square without using any built-in square root functions. A perfect square is an integer that can be expressed as the product of an integer with itself.
Example 1:
Input: num = 16
Output: true
Explanation: 4 * 4 = 16
Example 2:
Input: num = 14
Output: false
Explanation: There is no integer x such that x * x = 14
Constraints:
1 <= num <= 2^31 - 1
Describe and implement an algorithm to solve this problem efficiently. Explain the time and space complexity of your solution. Discuss potential edge cases and how your solution handles them.
A simple approach is to iterate through numbers from 1 up to num
and check if the square of any of these numbers equals num
. If we find such a number, then num
is a perfect square; otherwise, it is not.
def is_perfect_square_brute_force(num):
i = 1
while i * i <= num:
if i * i == num:
return True
i += 1
return False
Time Complexity: O(√n), where n is the input number num
.
Space Complexity: O(1), as we only use a constant amount of extra space.
Since we are looking for a specific value within a sorted range (1 to num
), binary search is an efficient way to find the square root. We can apply binary search to find an integer x
such that x*x == num
. If we find such an x
, then num
is a perfect square. This avoids the need to iterate through every possible value up to the square root.
def is_perfect_square_binary_search(num):
left, right = 1, num
while left <= right:
mid = left + (right - left) // 2
square = mid * mid
if square == num:
return True
elif square < num:
left = mid + 1
else:
right = mid - 1
return False
Time Complexity: O(log n), where n is the input number num
.
Space Complexity: O(1), as we only use a constant amount of extra space.
1 <= num <= 2^31 - 1
, so num
cannot be zero. However, for completeness, if zero were allowed, it should return true because 0 * 0 = 0.mid * mid
should not cause overflow, so using long
may be necessary in languages like Java or C++ depending on the constraint for num, but not Python.The binary search approach offers a significant improvement in time complexity compared to the brute-force method, making it the optimal solution for determining whether a number is a perfect square.