Skip to content

Commit d07c6e2

Browse files
solves perfect squares
1 parent 52ea603 commit d07c6e2

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@
228228
| 276 | 🔒 [Paint Fence](https://leetcode.com/problems/paint-fence) | | |
229229
| 277 | 🔒 [Find The Celebrity](https://leetcode.com/problems/find-the-celebrity) | | |
230230
| 278 | [First Bad Version](https://leetcode.com/problems/first-bad-version) | [![Java](assets/java.png)](src/FirstBadVersion.java) [![Python](assets/python.png)](python/first_bad_version.py) | |
231-
| 279 | [Perfect Squares](https://leetcode.com/problems/perfect-squares) | | |
231+
| 279 | [Perfect Squares](https://leetcode.com/problems/perfect-squares) | [![Java](assets/java.png)](src/PerfectSquares.java) | |
232232
| 280 | 🔒 [Wiggle Sort](https://leetcode.com/problems/wiggle-sort) | | |
233233
| 281 | 🔒 [Zigzag Iterator](https://leetcode.com/problems/zigzag-iterator) | | |
234234
| 283 | [Move Zeroes](https://leetcode.com/problems/move-zeroes) | [![Java](assets/java.png)](src/MoveZeros.java) [![Python](assets/python.png)](python/move_zeroes.py) | |

src/PerfectSquares.java

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,44 @@
11
// https://leetcode.com/problems/perfect-squares
2-
// T: O(N * k) k = size of perfect squares array which is constant
3-
// S: O(N + k)
2+
// T: O(k + sqrt(n)) k = size of perfect squares set which is constant
3+
// S: O(k)
4+
5+
import java.util.Set;
46

57
public class PerfectSquares {
6-
private static final int[] PERFECT_SQUARES = {
8+
private static final Set<Integer> PERFECT_SQUARES = Set.of(
79
1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576,
810
625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849,
911
1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721,
1012
3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241,
1113
6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409,
12-
9604, 9801, 10000, 10_201
13-
};
14+
9604, 9801, 10_000, 10_201
15+
);
1416

15-
public int numSquares(int n) {
16-
final int[] dp = new int[n + 1];
17-
dp[0] = dp[1] = 1;
18-
for (int i = 2 ; i < dp.length ; i++) {
19-
dp[i] = numSquares(i, dp);
20-
}
21-
return dp[dp.length - 1];
17+
private boolean isSquare(int n) {
18+
return PERFECT_SQUARES.contains(n);
2219
}
2320

24-
private int numSquares(int n, int[] dp) {
25-
int result = Integer.MAX_VALUE, square;
26-
for (int i = 0 ; PERFECT_SQUARES[i] <= n ; i++) {
27-
square = PERFECT_SQUARES[i];
28-
result = Math.min(result, dp[square] + dp[n - square]);
21+
// Based on Lagrange's Four Square theorem, there
22+
// are only 4 possible results: 1, 2, 3, 4.
23+
int numSquares(int n) {
24+
// If n is a perfect square, return 1.
25+
if (isSquare(n)) return 1;
26+
27+
// The result is 4 if and only if n can be written in the
28+
// form of 4^k*(8*m + 7). Please refer to
29+
// Legendre's three-square theorem.
30+
while (n % 4 == 0) {
31+
n >>= 2;
2932
}
30-
return result;
33+
if (n % 8 == 7) return 4;
34+
35+
// Check whether 2 is the result. if number can be composed as a^2 + b^2
36+
for(int i = 1; i * i <= n; i++) {
37+
if (isSquare(n - i * i)) {
38+
return 2;
39+
}
40+
}
41+
42+
return 3;
3143
}
3244
}

0 commit comments

Comments
 (0)