Question:
Given a positive integer num, write a function which returns True if num is a perfect square else False.
Note: Do not use any built-in library function such as sqrt.
Example 1:
Input: 16
Returns: True
Example 2:
Input: 14
Returns: False
Solution 1:
首先尝试暴力求解,时间复杂度是O(n),发现超时。然后想着用二分,发现还是超时,最后用了一个O(根号n)的方法就过了。
但是二分是O(logn)啊,比O(根号n)要好,但是却超时,我又把下面O(根号n)的代码中的i <= num/i
改为了i*i <= num
发现就超时了,这只能说明除法的效率比乘法高或者两个较小的数比较大小比两个较大的数比较大小效率要高,或者还有其他原因?
class Solution {
public:
bool isPerfectSquare(int num) {
if (num < 0) return false;
if (num == 0 || num == 1) return true;
for (int i = 1; i <= num / i; i++) {
if (i * i == num)
return true;
}
return false;
}
};
Solution 2:
这个是从网上找的一个O(1)的方法,简直丧心病狂。原理还是没看懂。那个i
更是不知道怎么得来的。
附上一个相关的连接。
https://en.wikipedia.org/wiki/Fast_inverse_square_root
class Solution {
public:
bool isPerfectSquare(int num) {
if (num < 0) return false;
int root = floorSqrt(num);
return root * root == num;
}
int32_t floorSqrt(int32_t x) {
double y=x; int64_t i=0x5fe6eb50c7b537a9;
y = *(double*)&(i = i-(*(int64_t*)&y)/2);
y = y * (3 - x * y * y) * 0.5;
y = y * (3 - x * y * y) * 0.5;
i = x * y + 1; return i - (i * i > x);
}
};