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
.
"Problem Analysis"
A number can be summed up by a number of complete squares, such as 1,4,9,16,...
Given a number n, the number of total squares required to make the sum of the sums as n is the minimum.
Ideas
1. Recursion
For a number, how do we ask for it to be summed up by the total number of squares?
First we find the nearest complete square m = x*x, we select a number from the 1~x, and we get the Z-x*x in N, and we recursively calculate the total square number that the n-z*x*x contains. Iterates through the 1~x, returning the smallest result.
2. Dynamic planning
Dynamic planning uses the Dp[i] array to store the number of perfect squares of number I. The recursion is: dp[i] = Math.min (Dp[j] + dp[i-j], dp[i]), that the complete sum of squares of I is the sum of the sum of two total squares dp[j] and dp[i-j] from and to I, and then take the smallest from it.
3. Improved dynamic planning
, the red part represents the square number, and all the numbers can be considered as a normal number plus a perfect square number, then the recursive formula becomes: Dp[i + J * j] = Math.min (Dp[i] + 1, Dp[i + J * j]).
"Java Recursive implementation"
1 Public classSolution {2 Public intNumsquares (intN) {3 intCount =N;4 intNearest = (int) math.sqrt (n);5 if(n = = 0)return0;6 if(Nearest*nearest = = N)return1;7 for(inti = nearest; I >= 1; i--) {8 intCur = 0, num = N, t = i*i;9 while(num-t >= 0) {Tennum-=T; Onecur++; A } - if(Cur <count) { -Count = Math.min (numsquares (num) +cur, count); the } - } - - returncount; + } -}
Time 606ms
"Java for dynamic planning"
1 Public classSolution {2 /*3 the idea of dynamic programming to solve, recursive formula dp[i] = Math.min (Dp[j] + dp[i-j], dp[i])4 */5 Public intNumsquares (intN) {6 int[] Array =New int[N+1];7 Arrays.fill (array, integer.max_value);8ARRAY[1] = 1;9 Ten for(inti = 2; I <=n; i++) { One intSqr = (int) math.sqrt (i); A if(SQR*SQR = = i) array[i] = 1; - Else{ - for(intj = 1; J <= I/2; J + +) { theArray[i] = math.min (array[j]+array[i-J], Array[i]); - } - } - } + returnArray[n]; - } +}
Time: 1112ms
"Java implementation improved dynamic planning"
1 Public classSolution {2 /*3 improved dynamic planning, recursive formula dp[i+j*j] = Math.min (dp[i]+1, dp[i+j*j])4 */5 Public intNumsquares (intN) {6 int[] Array =New int[N+1];7 Arrays.fill (array, integer.max_value);8 9 for(inti = 1; I*i <= N; i++) {TenArray[i*i] = 1; One } A for(inti = 1; I <= N; i++) { - for(intj = 1; I+j*j <= N; J + +) { -ARRAY[I+J*J] = math.min (array[i]+1, array[i+j*j]); the } - } - returnArray[n]; - } +}
Time: 60ms
Leetcode 279. Perfect Squares