133/300
- 完全平方数
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/perfect-squares
思路:bfs
第一步:我们要找的数肯定是小于等于 12 \sqrt{12} 12, 9 ≤ 12 ≤ 16 9\leq\sqrt{12}\leq16 9≤12≤16, 所以也就是{1,2,3}    ⟹    \implies ⟹ {1,4,9}。 换个角度:如果是4,4的平方就是16,比12大,肯定不需要。
第二步:做减法。
第一轮:
{
12
−
1
,
12
−
4
,
12
−
9
}
→
{
11
,
8
,
3
}
\{12-1,12-4,12-9\} \to \{11,8,3\}
{12−1,12−4,12−9}→{11,8,3}
{
11
,
8
,
3
}
&
{
1
,
4
,
9
}
↦
N
o
n
e
\{11,8,3\}\&\{1,4,9\} \mapsto None
{11,8,3}&{1,4,9}↦None
第二轮:
{
11
−
1
,
11
−
4
,
11
−
9
,
8
−
1
,
8
−
4
,
8
−
9
,
3
−
1
,
3
−
4
,
3
−
9
}
→
{
10
,
7
,
2
,
4
}
\{11-1,11-4,11-9, 8-1,8-4,\cancel{8-9}, 3-1,\cancel{3-4},\cancel{3-9}\} \to \{10,7,2,4\}
{11−1,11−4,11−9,8−1,8−4,8−9
,3−1,3−4
,3−9
}→{10,7,2,4}
{
10
,
7
,
2
,
4
}
&
{
1
,
4
,
9
}
↦
{
4
}
\{10,7,2, 4\}\&\{1,4,9\} \mapsto \{4\}
{10,7,2,4}&{1,4,9}↦{4}
第三步:一共有三个4: 12-4 → \to → 8 - 4 → \to → 4
class Solution:
def numSquares(self, n: int) -> int:
candidates = set([ i*i for i in range(int(n**0.5)+1)])
def bfs(nums):
if nums & candidates: return 1
tmp = set([num - candi for num in nums for candi in candidates if num - candi >= 0 ])
return bfs(tmp)+1
return bfs(set([n]))