"""
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
"""
# 动态规划
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:
visited.add(diff)
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)
279_完全平方数
最新推荐文章于 2021-05-21 21:43:55 发布