题目:
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...
)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例:
输入: n = 12 输出: 3 解释: 12 = 4 + 4 + 4.
输入: n = 13 输出: 2 解释: 13 = 4 + 9.
来源:力扣(LeetCode) 链接:https://https://leetcode-cn.com/problems/perfect-squares/
解法一:
递归的方法
f(n):
1.如果n是一个完全平方数,则返回1;
2.如果n不是一个完全平方数,让n依次减去小于n的完全平方数->x,去计算和为x的最少完全平方和个数f(x);
3.f(n) = min(f(x))+1
问题:随着n的上升,时间复杂度会迅速增大,超出时间限制。
class Solution:
# def numSquares(self, n: int) -> int:
# x = n**0.5
# if(x%1==0):
# return 1
# else:
# num = float("inf")
# x = int(x)
# while(x>0):
# a = 0
# a = a + self.numSquares(n-(x**2))
# a += 1
# if a<num:
# num = a
# if b<num:
# num = b
# if num==2:
# break
# x -= 1
# return num
解法二:
队列+BFS
1. 建立一个队列value存储当前所有相加得到的值,建立一个队列存储步数;
2.对于列首的值依次相加所有小于n的完全平方数,并对相加后的值x进行判断:
a.x=n, 返回结果
b.x<n,判断其是否已在队列里,如不在添加进队列
c.x>n, 停止本循环,换为队列的下一个值继续该过程。
(遍历时,一定要去重复,否则时间复杂度也会很高)
class Solution:
def numSquares(self, n: int) -> int:
x = n**0.5
if(x%1==0):
return 1
else:
x = int(x)
step = []
value = []
used_value = [0]*n
i = 1
while(i<=x):
value.append(i**2)
step.append(1)
i += 1
j = 0
while(1):
for i in range(x+1):
a = value[0]+i**2
s = step[0]+1
if(a==n):
return s
elif(a<n):
if(used_value[a] == 0):
value.append(a)
step.append(s)
used_value[a] =1
elif(a>n):
break
i+=1
del value[0]
del step[0]