forked from weiliu89/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PerfectSquares.cpp
98 lines (85 loc) · 2.78 KB
/
PerfectSquares.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Source : https://leetcode.com/problems/perfect-squares/
// Author : Hao Chen
// Date : 2015-10-25
/***************************************************************************************
*
* 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.
*
* Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating
* all test cases.
*
***************************************************************************************/
class Solution {
public:
int numSquares(int n) {
return numSquares_dp_opt(n); //12ms
return numSquares_dp(n); //232ms
}
/*
* Dynamic Programming
* ===================
* 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[6] = min{ dp[6-1*1]+1, dp[6-2*2]+1 }
* = min{ dp[5]+1, dp[2]+1 }
* = 3
* dp[7] = min{ dp[7-1*1]+1, dp[7-2*2]+1 }
* = min{ dp[6]+1, dp[3]+1 }
* = 4
* dp[8] = min{ dp[8-1*1]+1, dp[8-2*2]+1 }
* = min{ dp[7]+1, dp[4]+1 }
* = 2
* dp[9] = min{ dp[9-1*1]+1, dp[9-2*2]+1, dp[9-3*3] }
* = min{ dp[8]+1, dp[5]+1, dp[0]+1 }
* = 1
* dp[10] = min{ dp[10-1*1]+1, dp[10-2*2]+1, dp[10-3*3] }
* = min{ dp[9]+1, dp[6]+1, dp[1]+1 }
* = 2
* ....
*
* So, the dynamic programm formula is
*
* dp[n] = min{ dp[n - i*i] + 1 }, n - i*i >=0 && i >= 1
*
*/
int numSquares_dp(int n) {
if ( n <=0 ) return 0;
int *dp = new int[n+1];
dp[0] = 0;
for (int i=1; i<=n; i++ ) {
int m = n;
for (int j=1; i-j*j >= 0; j++) {
m = min (m, dp[i-j*j] + 1);
}
dp[i] = m;
}
return dp[n];
delete [] dp;
}
//using cache to optimize the dp algorithm
int numSquares_dp_opt(int n) {
if ( n <=0 ) return 0;
static vector<int> dp(1, 0);
if (dp.size() >= (n+1) ) return dp[n];
for (int i=dp.size(); i<=n; i++ ) {
int m = n;
for (int j=1; i-j*j >= 0; j++) {
m = min (m, dp[i-j*j] + 1);
}
dp.push_back(m);
}
return dp[n];
}
};