# 279 perfect squares

## 刷题内容

• https://leetcode.com/problems/perfect-squares
• https://leetcode-cn.com/problems/perfect-squares

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



## 解题方案

求某个数的最少平方加和的个数

1. diff集合(小到大排序) = n - 平方根的平方的集合
2. 每一层都在不断 - 平方根的平方
3. 直到出现 0 代表得到结果

n = 15 的时候
-9  -4  -1
>>> [6, 11, 14]
>>> [2, 5, 7, 10, 13]
>>> [1, 3, 4, 6, 9, 12]
>>> [0, 2, 3, 5, 8, 11]
>>> [1, 2, 4, 7, 10]
>>> [0, 1, 3, 6, 9]
>>> [0, 2, 5, 8]
>>> [1, 4, 7]
>>> [0, 3, 6]
>>> [2, 5]
>>> [1, 4]
>>> [0, 3]
>>> [2]
>>> [1]
>>> [0]
>>> []
4  ---  [4, 6, 7, 9, 12, 15]

class Solution(object):
def numSquares(self, n: int) -> int:
result = []
count = 1
diff_list = [n]
while len(diff_list):
diff_list = sorted(list(set([diff-i**2 for diff in diff_list for i in range(1, diff+1) if diff>=i**2])))
# print(">>> %s" % diff_list)
if len(diff_list) < 1:
break
elif 0 in diff_list:
result.append(count)
count += 1
# print(min(result), " --- ", result)
return min(result) if len(result)>0 else -1


1. 初始化 inf 从0开始，所以数组长度 n+1
2. 考虑到是平方，意味着他的间隔可能是跳跃性的，所以
n  =   (n-j*j)  + j*j
dp[i] = dp[i-1] + 1
3. 那么 min 就是未来找到最小值而存在的，因为需要遍历很多个平方， dp[i] 用户存储最小值
4. 返回 dp[-1] 的结果，也就是最终 n 的值

class Solution(object):
def numSquares(self, n: int) -> int:
square_nums = [i**2 for i in range(1, int(n**0.5)+1)]
dp = [float('inf')] * (n+1)
dp[0] = 0
for i in range(1, n+1):
for square in square_nums:
if i < square:
break
# print("%s --- %s结果需要一次 --- %s结果需要%s次" % (i, square, i-square, dp[i-square]))
dp[i] = min(dp[i], dp[i-square] + 1)
return dp[-1]


import math
class Solution(object):
def numSquares(self, n):
"""
:type n: int
:rtype: int
"""
def isSquare(num):
tmp = int(math.sqrt(num))
return tmp * tmp == num
while n & 3 == 0: # n % 4 == 0
n >>= 2
if n & 7 == 7: # n % 8 == 7
return 4
if isSquare(n):
return 1
sqrt_n = int(math.sqrt(n))
for i in range(1, sqrt_n + 1):
if isSquare(n-i*i):
return 2
return 3


in order to understand, I suggest u read:

here is the Lagrange's Four Square theorem - Limit the result to <= 4:

And this article, in which you can also find the way to present a number as a sum of four squares:

apachecn/AiLearning