effective perfect square
1. Topic
Given a positive integer num, write a function that returns true if num is a perfect square, and false otherwise.
Advanced: Do not use any built-in library functions such as sqrt.
Example 1:
Input: num = 16
Output: true
Example 2:
Input: num = 14
Output: false
hint:
1 <= num <= 231 - 1
2. Idea
2.1 Violent solution
Because a positive integer num is given, it starts to traverse from 1, and needs to traverse at most num + 1 \sqrt {num} + 1num+1 time.
Complexity Analysis
- Time complexity: O ( n ) O(\sqrt{n})O(n) , where n is the maximum value of positive integer num. We need to traverse at mostn + 1 \sqrt{n} + 1n+1 positive integer.
- Space complexity: O ( 1 ) O(1)O(1)。
2.2 Binary search
You can use the dichotomy method to search in the left-closed right-closed interval [1, num]
Complexity Analysis
- Time complexity: O ( log n ) O(\log n)O(logn ) , where nn is a positive integernum numThe maximum value of n u m .
- Space complexity: O ( 1 ) O(1)O(1)
2.3 Newton iteration method
The core idea: with the help of Taylor series, quickly approach the zero point of the function from the initial value.
- Set up the equation: y = f ( x ) = x 2 − numy = f(x) = x^2 - numy=f(x)=x2−num
- Compute the next iteration value:
- Derivative, y ′ = 2 x y' = 2xy′=2x _
- 直线方程, y − ( x i 2 − n u m ) = 2 x i ( x − x i ) y - (x_i^2 - num) = 2x_i(x - x_i) y−(xi2−num)=2x _i(x−xi)
- The intersection of the line equation and the x-axis, xi + 1 = x = 1 2 ( xi + numxi ) x_{i+1} = x = \frac{1}{2}(x_i + \frac{num}{x_i})xi+1=x=21(xi+xinum)
- Termination condition: determine whether the difference between the results of two adjacent iterations is less than a very small non-negative number ϵ ϵϵ,whereinϵϵϵ can generally take1 0 − 6 or 1 0 − 7 10^{-6} or 10^{-7}10− 6 or10−7
Complexity Analysis
- Time complexity: O ( log n ) O(\log n)O(logn ) , where nn is a positive integernum numThe maximum value of n u m .
- Space complexity: O ( 1 ) O(1)O(1)
3. Code implementation
binary search
class Solution {
public:
bool isPerfectSquare(int num) {
int left = 1;
int right = num;
while(left <= right){
int middle = left + (right - left)/2;
long square = (long) middle * middle;
// 小了,找右区间,left右移
// 大了,找左区间,right左移
if(square < num) left = middle + 1;
else if(square > num) right = middle - 1;
else return true;
}
return false;
}
};
- Note: square has the risk of overflow
Newton iteration method
class Solution {
public:
bool isPerfectSquare(int num) {
double x0 = num;
double esp = 1e-6;
while(true){
double x1 = (x0 + num / x0) / 2;
if((x0 - x1) < esp) break;
x0 = x1;
}
int x = int(x0);
return x * x == num;
}
};
- In the Newton iteration method, because xi x_ixiAlways move left, so x 0 − x 1 x_0 - x_1x0−x1Must be greater than or equal to zero