-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy path_996.java
58 lines (50 loc) · 1.64 KB
/
_996.java
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
import java.util.Arrays;
/**
* LeetCode 996 - Number of Squareful Arrays
*
* Hamiltonian Path
* Some special effort is needed to avoid double counting paths that look the same.
*/
public class _996 {
boolean[][] g;
public int numSquarefulPerms(int[] A) {
int n = A.length;
Arrays.sort(A);
g = new boolean[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
g[i][j] = isSquare(A[i] + A[j]);
}
}
int[][] f = new int[1 << n][n];
for (int mask = 1; mask < (1 << n); mask++) {
for (int i = 0; i < n; i++) {
if ((mask & (1 << i)) != 0) {
if ((mask - (1 << i)) == 0) {
f[mask][i] = 1;
} else {
int last = -1; // Avoid double counting
for (int pre = 0; pre < n; pre++) {
if (g[pre][i] && pre != i && (mask & (1 << pre)) != 0 && last != A[pre]) {
f[mask][i] += f[mask - (1 << i)][pre];
last = A[pre];
}
}
}
}
}
}
int ans = 0, last = -1;
for (int i = 0; i < n; i++) {
if (A[i] != last) {
ans += f[(1 << n) - 1][i];
last = A[i];
}
}
return ans;
}
boolean isSquare(int x) {
long root = (int) Math.sqrt(x);
return root * root == x || (root - 1) * (root - 1) == x || (root + 1) * (root + 1) == x;
}
}