Skip to content

Commit f39c258

Browse files
committed
Implement perfect-squares
name: perfect-squares url: https://leetcode.com/problems/perfect-squares difficulty: 2 time: 67.23 ms time-rank: -1 % time-complexity: O(N^2) space: 9.1 MB space-rank: 67.41 % space-complexity: O(N) Fixes #309 Signed-off-by: Christopher Friedt <[email protected]>
1 parent 87034c4 commit f39c258

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

perfect-squares-test.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2021, Christopher Friedt
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#include <gtest/gtest.h>
8+
9+
#include "perfect-squares.cpp"
10+
11+
using namespace std;
12+
13+
TEST(PerfectSquares, 1) {
14+
EXPECT_EQ(1, Solution().numSquares(1));
15+
}
16+
17+
TEST(PerfectSquares, 2) {
18+
EXPECT_EQ(2, Solution().numSquares(2));
19+
}
20+
21+
TEST(PerfectSquares, 3) {
22+
EXPECT_EQ(3, Solution().numSquares(3));
23+
}
24+
25+
TEST(PerfectSquares, 4) {
26+
EXPECT_EQ(1, Solution().numSquares(4));
27+
}
28+
29+
TEST(PerfectSquares, 9) {
30+
EXPECT_EQ(1, Solution().numSquares(9));
31+
}
32+
33+
TEST(PerfectSquares, 12) {
34+
EXPECT_EQ(3, Solution().numSquares(12));
35+
}
36+
37+
TEST(PerfectSquares, 13) {
38+
EXPECT_EQ(2, Solution().numSquares(13));
39+
}

perfect-squares.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2021, Christopher Friedt
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
// clang-format off
8+
// name: perfect-squares
9+
// url: https://leetcode.com/problems/perfect-squares
10+
// difficulty: 2
11+
// clang-format on
12+
13+
#include <climits>
14+
#include <vector>
15+
16+
using namespace std;
17+
18+
class Solution {
19+
public:
20+
int numSquares(int n) {
21+
// n | r(n) | comment
22+
// --------------
23+
// 1 | 1 | 1 is itself a perfect square
24+
// 2 | 2 | 1 + 1
25+
// 3 | 3 | 1 + 1 + 1
26+
// 4 | 1 | 4 is itself a perfect square
27+
// 5 | 2 | 4 + 1
28+
// 6 | 3 | 4 + 1 + 1
29+
// 7 | 4 | 4 + 1 + 1 + 1
30+
// 8 | 2 | 4 + 4
31+
// 9 | 1 | 9 is itself a perfect square
32+
// 10 | 2 | 9 + 1
33+
// 11 | 3 | 9 + 1 + 1
34+
// 12 | 3 | 4 + 4 + 4
35+
// 13 | 2 | 9 + 4
36+
//
37+
// r(n) = min(1 + r(n-k), r(n))
38+
//
39+
// how to determine k?
40+
//
41+
// k is a perfect square that is <= n
42+
//
43+
// maintaining a map even of perfect squares for numbers up to
44+
// n could be O(N^2) space, at least, and the time to generate
45+
// them would be O(N) at least. If we had a list of them, there
46+
// would be O(N^2) ways per number, which would eaqual O(N^3) time.
47+
//
48+
// This dp approach is O(N^2) time and O(N) space
49+
50+
vector<int> dp(n + 1, INT_MAX);
51+
dp[0] = 0;
52+
53+
for(int j = 1; j <= n; ++j) {
54+
for(int i = 1, k = i*i; k <= j; ++i, k = i*i) {
55+
dp[j] = min(dp[j], 1 + dp[j - k]);
56+
}
57+
}
58+
59+
return dp[n];
60+
}
61+
};

0 commit comments

Comments
 (0)