- 想不出来,看解析的思路写的动态规划:
class Solution:
def numSquares(self, n: int) -> int:
# 动态规划
# dp[i]指i这个数化作完全平方数的和的个数
# 动态规划就是要利用好前面已经计算的数的结果,假设前面的数的结果都计算好了。
# 在前面某个数[1, i-1]上能不能跳一步到现在的数i,跳一步:只加一个数j的完全平方数到达i。
# 那能使得跳一步的这个数j的范围是多少呢?[1,根号i]
# 假如是根号i的话,就是说i本身就是完全平方数,相当于0+(根号i)^2,所以dp[0]=0就是为了这个时候好和其他的跳法兼容一下。
# 假如是1的话,就是说dp[i - 1^2] + 1步
# 假如是j的话,就是dp[i - j^2] + 1步;
# 总结就是找到前面dp[i - j^2]中的最小值,+1步(也就是+j^2=i) = dp[i]
import math
dp = [0] * (n+1)
for i in range(1, n+1):
for j in range(1, int(math.sqrt(i)) + 1):
if j == 1: minn = dp[i - 1]
else:
minn = min(minn, dp[i - j**2])
dp[i] = minn + 1
return dp[n]
时间快要爆炸了啊喂
- 数学公式:四平方定理
写了自己的理解:
import math
class Solution(object):
def numSquares(self, n):
while n % 4 == 0: # 对应循环a次
n /= 4
if n % 8 == 7: return 4 # 符合四平方定理
a = 0
# 判断是否可以用1个数的平方还是2个数的平方。如果遍历完都不行,那就只能是3了
while a ** 2 <= n:
b = int((n - a**2) ** 0.5) # a是第一个数,b是第二个数
if a ** 2 + b ** 2 == n:
return (not not a) + (not not b)
# 第一个not将a/b化成布尔值,第二个not是布尔的非,还原a/b的大致真假属性
# 假设此时a=0就进来了,也就是说b**2 = n,答案就是1
# 这个处理超级妙啊
a += 1 # 遍历中
return 3
没有对比就没有伤害…数学yyds