Python算法——2.完全平方


写在前面

此为博主在学习Python算法中遇到的案例做的学习笔记,案例来自《Python算法指南——程序员经典算法分析与实现》,源代码参考该书。


问题描述

给定一个正整数,判断其是否为完全平方数。

问题示例

该数满足开方后的数再平方等于本身即为完全平方数,如25 = 5²为完全平方数。

问题解决

给定一个正整数n,最简单的方法即遍历1到(n-1)的每个数判断其平方是否等于n,这样的时间复杂度为O(n)。
可稍微改进下,由均值不等式可知,算数平均(1+n)/ 2 ≥ √n,于是可以将遍历范围缩小,从1到(1+n) / 2,但这样子算的时间复杂度仍为O(n)。
在《数据结构》中学过折半查找的方法,该方法使查找范围不断缩小一半,直至找到或找完时间复杂度为O(n)= log2(N)将这种思想应用在这道题上。
令初始的探索范围下边界low为1,上边界high为n,中间值min = (1+n)/ 2,比较min²与n的大小,若前者小说明要找的值比mid大,在mid的右边,即修改探索范围下边界low为mid;否则修改上边界的值为high,重复上述操作直至两边界为相邻整数。
取最后的下边界为结果ans,若ans²比n小则取上边界的结果为ans,比较ans²与n是否相等即可。
导入math库调用sqrt()也可以实现相应功能。
根据上述分析编写代码如下:

import  math

class Solution:
    '''不调用外部函数'''
    def isSquare1(self,n):
        low = 1
        high = n
        while(high - low > 1):
            mid = int((high + low) / 2)
            print("low = ",low,"mid = ",mid,"high = ",high,'\n')
            if(mid * mid <= n):
                low = mid
            else:
                high = mid
        print("low = ",low,"mid = ",mid,"high = ",high,'\n')
        ans = low
        if(low * low < n):
            ans = high
        return ans * ans == n
    
    def isSquare2(self,n):
        return (int(math.sqrt(n))) ** 2 == n
    
if __name__ == "__main__":
    print("输入值:")
    n = int(input())
    print("值:",n)
    solution = Solution()
    print("1.是否为完全平方数:",solution.isSquare1(n))
    print("2.是否为完全平方数:",solution.isSquare2(n))

测试结果打印如下:
1
2


总结

这道题比较简单,但也回顾了折半查找。对于一些查找值且范围巨大的算法,可以用折半查找减小算法的时间复杂度。

猜你喜欢

转载自blog.csdn.net/weixin_47585015/article/details/110959176