Perfect Squares
#math #dynamicprogramming
Given a positive integer n, find the least number of perfect square numbers (for example,1, 4, 9, 16, ...) which sum to n.
Example 1:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.Example 2:
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.Analysis
Dynamic Programming
用DP关键在于定义状态和找到转化关系。这里用dp[i]代表对i的perfect squares count,转化关系并不是很直观:
dp[n] = Min{ dp[n - i*i] + 1 }, for n - i*i >=0 && i >= 1具体推理如下:
The most intuitive approach besides brute force would probably be dynamic programming, whether it's bottom up iteration or recursion with memoization, they all based on the recurrence relation:
dp[0] = 0
dp[1] = dp[0]+1 = 1
dp[2] = dp[1]+1 = 2
dp[3] = dp[2]+1 = 3
dp[4] = Min{ dp[4-1*1]+1, dp[4-2*2]+1 }
= Min{ dp[3]+1, dp[0]+1 }
= 1
dp[5] = Min{ dp[5-1*1]+1, dp[5-2*2]+1 }
= Min{ dp[4]+1, dp[1]+1 }
= 2
.
.
.
dp[13] = Min{ dp[13-1*1]+1, dp[13-2*2]+1, dp[13-3*3]+1 }
= Min{ dp[12]+1, dp[9]+1, dp[4]+1 }
= 2
.
.
.
dp[n] = Min{ dp[n - i*i] + 1 }, for n - i*i >=0 && i >= 1where dp[n] stands for the perfect squares count of the given n
关于DP,这题的特点是 (by @mnmunknown):
要凑出来一个和正好是 n 的选择组合;
能选的元素是固定数量的 perfect square (有的会超) ;
一个元素可以选多次;
说明这其实是个背包问题。
Mathematical
See [[[[[)
BFS
用BFS乍一看较难理解,其实在于问题转化:
把数字0, 1, ..., n看成一个图graph的节点node,节点i, j 连接的条件是
j = i + (a perfect square number) or i = j + (a perfect square number)
已知起始点0,和终点n,这样问题就转化为一个最短路径问题。故使用BFS。
Solution
Dynamic Programming - Iterative Bottom Up (~ 22ms AC)
DP another version
Mathematical - (1ms AC)
Recursion Memoization (NOT RECOMMENDED) - (655ms AC 4.86% percentile)
BFS Version (~113ms 21.89%)
Reference
https://mnmunknown.gitbooks.io/algorithm-notes/82ff0c_bei_bao_wen_ti.html
Last updated
Was this helpful?