【日更 Day25】Leetcode 279

Type: Medium, BFS

完美平方数

题目描述:

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

Example 1:

Input: n = 12
Output: 3 
Explanation: 12 = 4 + 4 + 4.

Example 2:

Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.

这里还牵涉到一个理论是:四平方和定理。

每个正整数均可表示为4个整数的平方和。

所以,本题的答案只在1,2,3,4这四个里面了。

去验证下:

139 / 588 test cases passed.

这个能过139个测试样例的写法是:

import random
class Solution:
    def numSquares(self, n):
        """
        :type n: int
        :rtype: int
        """
        return random.randint(1,4)

随机1,2,3,4.

再测试只随机输出1,2,3,结果:

160 / 588 test cases passed.

还有提高哈。

严肃说明:这不是解题的正确态度,只是探索一下。

实际上,结合一个推论:

满足四数平方和定理的数n(这里要满足由四个数构成,小于四个不行),必定满足

可以知道,是四个整数组成的,比较特殊。

import random
class Solution:
    def numSquares(self, n):
        """
        :type n: int
        :rtype: int
        """
        # 根据推论,降低问题规模:4^a(8b + 7)
        while n % 4 == 0:
            n /= 4
        if n % 8 == 7:
            return 4
        
        a = 0
        while a ** 2 <= n:
            b = int((n - a ** 2) ** 0.5)
            if a ** 2 + b ** 2 == n:
                return (not not a) + (not not b)
            a += 1
            
        return 3

根据推论,4本身是平方数,所以可以不断除以4,得到的8b + 7假定是,带上4可以看成是。

缩减到只剩下8b+7后,就可以进行判断是否满足推论,否则开始暴力搜索,满足两个完全平方数的 ,则输出2,否则就是3.

DP解法

import random
class Solution:
    def numSquares(self, n):
        """
        :type n: int
        :rtype: int
        """

        # dp解法
        dp = [1e31] * (n + 1)
        a = int(n ** 0.5)
        for i in range(a + 1):
            dp[i * i] = 1
        for i in range(1,n + 1):
            b = int((n - i) ** 0.5) + 1
            for j in range(1,b):
                dp[i + j * j] = min(dp[i] + 1, dp[i + j * j])
                
        return dp[n]

参考链接:https://blog.csdn.net/happyaaaaaaaaaaa/article/details/51584790

END.

你可能感兴趣的:(【日更 Day25】Leetcode 279)