问题描述:
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...
) which sum to n.
For example, given n = 12
, return 3
because 12 = 4 + 4 + 4
; given n = 13
, return 2
because 13 = 4 + 9
.
算法:
使用最接近n的平方数的平方根nearst进行标记。
构建数组array长度为n+1,将array[0]废置。
从1到n迭代array的index:
如果index为nearst**2则array[index] = 1
如果index为(nearst+1)**2则array[index] = 1且nearst+=1
否则:寻找i从1 到nearst范围内的(array[(nearst-i)**2]+array[n-(nearst-i)**2])的最小值。
返回:return array[n]
时间复杂度:
O(n*sqrt(n)) 由于nearst 约等于 sqrt(n)
代码:
class Solution(object):
def numSquares(self, n):
"""
:type n: int
:rtype: int
"""
array = [10e6 for _ in range(n+1)]
nearst = 1
for num in range(1,n+1):
if num == nearst*nearst:
array[num] = 1
elif num == (nearst+1)*(nearst+1):
array[num] = 1
nearst += 1
else:
temp = array[nearst**2]+array[num-nearst**2]
for i in range(1,nearst):
if temp > array[(nearst-i)**2]+array[num-(nearst-i)**2]:
temp = array[(nearst-i)**2]+array[num-(nearst-i)**2]
array[num] = temp
return array[n]
但是结果超时,这段代码中可以使用缓存以及列表表达式的方法进行优化。优化的方式可以使用类变量也可以使用装饰器,这里使用类变量比较方便,因为所调用函数中没有出现递归调用,反而数组array的存在举足轻重。可以将array作为类变量。
优化:
class Solution(object):
#600 tests 1160ms
cache = [0]
def numSquares(self, n):
"""
:type n: int
:rtype: int
"""
cache = Solution.cache
if n <= len(cache)-1:
return cache[n]
array = [10e6 for _ in range(n+1)]
nearst = 1
for num in range(1,n+1):
if num == nearst*nearst:
array[num] = 1
elif num == (nearst+1)*(nearst+1):
array[num] = 1
nearst += 1
else:
array[num] = min([array[(nearst-i)**2]+array[num-(nearst-i)**2] for i in range(nearst)])
length = len(cache)
for i in range(length, len(array)):
cache.append(array[i])
return array[n]