Perfect Squares - leetcode-高级

'''
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

示例 1:

输入: n = 12
输出: 3 
解释: 12 = 4 + 4 + 4.
示例 2:

输入: n = 13
输出: 2
解释: 13 = 4 + 9.
'''

'''
解法一:思路很简单和前面的硬币那个差不多https://blog.csdn.net/wqtltm/article/details/81430004,就不多说了,这里我主要想用用生成器。时间复杂度o(n^1.5)
'''

def numSquares(self, n):
    """
    :type n: int
    :rtype: int
    """
    import math
    def generator(n):
        x=1
        while x<math.sqrt(n):
            yield x**2
            x+=1
    nums = [n+1 for i in range(n+1)]
    nums[0]=0
   
    for i in range(n+1):
        if nums[i]<n+1:
            gen = generator(n)
            for value in gen:
                if i+value<=n:
                    nums[i+value] = min(nums[i+value],nums[i]+1)
                    


    return nums[-1]

'''
解法二:解法一,虽然可行也很高效,但是针对平方数这么有特点的数肯定不是 最优的解法,最优的解法用到了四平方和定理
根据四平方和定理,任意一个正整数均可表示为4个整数的平方和,其实是可以表示为4个以内的平方数之和,那么就是说返回结果只有1,2,3或4其中的一个,
首先,一个数如果可以整除4那么 这个数除以四之后得到的那个数和这个数得到的结果是相同的,也就是说64和16,16和4返回的结果都相同,具体证明我也不会

还有一个可以化简的地方就是,如果一个数除以8余7的话,那么肯定是由4个完全平方数组成,并且所有由4平方组成的数都有余7的特性。这个我也不会证明
那我们发现余4的数字解决了,下面我们就来尝试的将其拆为两个平方数之和,如果拆成功了那么就会返回1或2,代码的int(y>0)+int(x>0)表示两个都不为0就返回2,否则是1,他们是不可能同时为0的
最后剩余的就是3了。。。。。。怎么说呢,数学味道太浓了   渣渣我要哭了。 时间复杂度o(n)
看代码
'''
 

def numSquares(self, n):
    """
    :type n: int
    :rtype: int
    """
    import math
    while n%4==0:
        n/=4
    if n%8==7:
        return 4
    for x in range(int(math.sqrt(n))+1):
        y = int(math.sqrt(n-x**2))
        if y**2+x**2==n:
            return int(y>0)+int(x>0)
    return 3

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值