题目

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.

方案一(BFS)

image.png
**

  1. import functools
  2. import collections
  3. class Solution:
  4. def numSquares(self, n: int) -> int:
  5. deque = collections.deque([n])
  6. res = 0
  7. while deque:
  8. length = len(deque)
  9. res += 1
  10. for _ in range(length):
  11. num = deque.popleft()
  12. for square_num in self.getSquareNumList(num):
  13. t = num - square_num
  14. if t == 0:
  15. return res
  16. deque.append(t)
  17. return -1
  18. @functools.lru_cache(maxsize=None)
  19. def getSquareNumList(self, n: int):
  20. '''获取小于等于n的完全平方数列表'''
  21. square_nums = []
  22. i = 1
  23. while i * i <= n:
  24. square_nums.append(i * i)
  25. i += 1
  26. return square_nums

方案二(数学定理)

Lagrange 四平方定理: 任何一个正整数都可以表示成不超过四个整数的平方之和。

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

  1. class Solution:
  2. def numSquares(self, n: int) -> int:
  3. if n < 4:
  4. return n
  5. # 4^k * (8a + 7)
  6. while n % 4 == 0:
  7. n /= 4
  8. if n % 8 == 7:
  9. return 4
  10. a = 0
  11. while a ** 2 <= n:
  12. b = int((n - a ** 2) ** 0.5)
  13. if a ** 2 + b ** 2 == n:
  14. return bool(a) + bool(b)
  15. a += 1
  16. return 3

方案三(动态规划)

  1. import functools
  2. class Solution:
  3. def numSquares(self, n: int) -> int:
  4. # 递推公式
  5. # dp[i] = min(dp[i], dp[i − j] + 1)
  6. dp = [i for i in range(n + 1)] # 初始化dp
  7. for i in range(2, n + 1):
  8. for j in self.getSquareNumList(i):
  9. dp[i] = min(dp[i], dp[i - j] + 1)
  10. return dp[-1]
  11. @functools.lru_cache(maxsize=None)
  12. def getSquareNumList(self, n: int):
  13. '''获取小于等于n的完全平方数列表'''
  14. square_nums = []
  15. i = 1
  16. while i * i <= n:
  17. square_nums.append(i * i)
  18. i += 1
  19. return square_nums

注意递推公式以及初始化dp

原文

https://leetcode-cn.com/explore/learn/card/queue-stack/217/queue-and-bfs/874/
https://leetcode-cn.com/problems/perfect-squares/solution/dong-tai-gui-hua-bfs-zhu-xing-jie-shi-python3-by-2/