# 279_完全平方数

"""

"""

# 动态规划
def numSquares(n):
dp = [float("inf")]*(n+1)
dp[0] = 0
for i in range(1, n+1):
for j in range(1, int(i**0.5)+1):
dp[i] = min(dp[i], dp[i-j*j]+1)
return dp[n]

# 动态规划
# class Solution:
#     _dp = [0]
#     def numSquares(self, n):
#         dp = self._dp
#         while len(dp) <= n:
#             dp += min(dp[-i*i] for i in range(1, int(len(dp)**0.5+1))) + 1,
#         return dp[n]

# 方法二 BFS
# 第一种速度慢
class Solution1:
def numSquares(self, n: int) -> int:
from collections import deque
if n == 0: return 0
queue = deque([n])
step = 0
visited = set()
while queue:
step += 1
l = len(queue)
for _ in range(l):
tmp = queue.pop()
for i in range(1, int(tmp ** 0.5) + 1):
diff = tmp - i ** 2
if diff == 0:
return step
if diff not in visited:
queue.appendleft(diff)
return step

# 第二种速度快
class Solution2:
def numSquares(self, n: int) -> int:
from collections import deque
if n == 0 or n == 1: return n
if int(n ** 0.5) ** 2 == n: return 1
queue = deque([n])
candidates = set([i ** 2 for i in range(1, int(n ** 0.5) + 1)])
step = 0
while queue:
step += 1
l = len(queue)
for _ in range(l):
tmp = queue.pop()
for x in candidates:
val = tmp - x
if val in candidates:
return step + 1
elif val > 0:
queue.appendleft(val)

08-10 862

05-29 150
06-25 277
09-23 1555
03-04 1万+
09-11