LeetCode#367: Valid Perfect Square

Description

Given a positive integer num, write a function which returns True if num is a perfect square else False.

Example

Input: 16
Output: true
Input: 14
Output: false

Solution

二分查找法

最容易想到的一种方法便是二分查找法。例如,当num=64时,我们查看32的平方是否等于64,很明显应该大于,所以再查看16的平方是否等于64,再查看8的平方是否等于64,这时候是等于的,因此返回true。

使用二分查找法最重要的一点是要把middle写成long类型,因为当整型的middle值太大时,middle * middle很有可能溢出。

public class Solution {
    public boolean isPerfectSquare(int num) {
        long lo = 1;
        long hi = num;
        long middle = lo + (hi - lo) / 2;
        while(lo <= hi) {
        	long pow = middle * middle;
        	if(pow < num) {
        		lo = middle + 1;
        	} else if(pow > num) {
        		hi = middle - 1;
        	} else {
        		return true;
        	}
        	middle = lo + (hi - lo) / 2;
        }
        return false;
    }
}

使用二分查找法的时间复杂度为O(logn)。

1+3+5…+n的数学规律

我们可以发现所有可以开平方的数都有为奇数相加这么一个特殊规律:

1:  1
4:  1+3
9:  1 + 3 + 5
16: 1 + 3 + 5 +7
25: 1 + 3 + 5 + 7 + 9
36: 1 + 3 + 5 + 7 + 9 + 11
...

因此我们要判断一个数是否可以开平方,可以将它不断的减去一个递增的奇数,直到其小于等于0。如果最后的结果等于0,说明其是由奇数组成的,也就是可以开平方的;否则,结果小于0,也就不能开平方。

因为平方根为6的数要相减6次,平方根为5的数要相减5次,以此类推可以得知这种解法的时间复杂度为O(sqrt(num))。

牛顿迭代法

知乎上有对牛顿迭代法进行较好的解释:

如何通俗易懂地讲解牛顿迭代法求开方?

这里对牛顿迭代公式进行进一步化简:
牛顿迭代公式

public class Solution3 {
	public boolean isPerfectSquare(int num) {
        long x = num;
        while (x * x > num) {
            x = (x + num / x) / 2;
        }
        return x * x == num;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值