题目描述
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
思路
切入点:
1.perfectSquare有特殊的性质
2.范围筛选排查类问题可以用递归、二分等方法缩小查找范围
算法1 递归拆解
将perfectSquare拆成的若干个数的乘积,这些数应该正好能分成相同的两份。按照这个思路,对所有num能整除的数a进行检查,是否num/a还能再整除一个a,如果是的话再递归的检查 num/a2 n u m / a 2 是否也能拆出两个相同的乘数。
考虑到特别大的素数,要对检查范围进行一个筛选。
class Solution {
public:
bool isPerfectSquare(int num) {
if(num==0)
return false;
if(num==1)
return true;
int top=min(num/2,99991);
for(int i=2;i<=top;i++)
{
if(num%i==0)
{
int devide=num/i;
if(devide==i)
return true;
else if(devide%i)
{
return isPerfectSquare(devide);
}
}
}
return false;
}
};
算法2 二分法接近开根后的值
既然不让开根号,将数的平方和num比较也是一样的。对于一些无法拆解的大质数,二分法可以迅速缩小范围,比上一个做法要快。
class Solution {
public:
inline long int square(long int a)
{
return a*a;
}
bool isPerfectSquare(int num) {
if(num==1)
return true;
if(num==0)
return false;
long int start=0;
long int end=num/2;
while(start<=end)
{
long int tmp=square((start+end)/2);
if(tmp==num)
return true;
else if(tmp>num)
end=(start+end)/2-1;
else if(tmp<num)
start=(start+end)/2+1;
}
return false;
}
};
正入万山圈子里,一山放过一山拦。
实在不是我勇敢,是滚滚红尘没有回头路呀。你一定要这么觉得,像这样走着的我,背影像个英雄。