Skip to content

Commit a918f2d

Browse files
authored
Create 3193-count-the-number-of-inversions.js
1 parent c146660 commit a918f2d

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* @param {number} n
3+
* @param {number[][]} requirements
4+
* @return {number}
5+
*/
6+
var numberOfPermutations = function(n, requirements) {
7+
// setup map/vector for tracking inversions
8+
let inv = new Array(n + 1).fill(-1);
9+
for (let req of requirements) {
10+
if (inv[req[0] + 1] === -1) {
11+
inv[req[0] + 1] = req[1];
12+
} else {
13+
return 0;
14+
}
15+
}
16+
17+
// sanity check
18+
// if length of the sequence is l
19+
// then there can be at most l*(l-1)/2 inversion pairs
20+
// in the case of decreasing order
21+
for (let i = 1; i <= n; i++) {
22+
if (inv[i] > (i * (i - 1)) / 2) {
23+
return 0;
24+
}
25+
}
26+
27+
// dp[len][inv]
28+
// solution for the prefix of length len, and inv inversion pairs
29+
30+
// setup dp
31+
const m = 400;
32+
const MOD = 1e9 + 7;
33+
let dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
34+
35+
// base case
36+
// i == 0, dp[0][j] = 0, j > 1, in memset
37+
// i == 0 && j == 0, dp[0][0] = 1
38+
dp[0][0] = 1;
39+
40+
/*
41+
Note:
42+
suppose we have a sequence of length (l-1), and we want to extend it to
43+
a sequence of length l, then what can happen to the number of inversion?
44+
45+
you can increase the number of inversions by at most (l-1).
46+
47+
so we need to check dp[i-1][j] for dp[i][c]
48+
where j = c-0, c-1, ..... , c-(l-1)
49+
*/
50+
51+
// recursion
52+
for (let i = 1; i <= n; i++) { // length
53+
// case 1, we have a requirement given
54+
// then just iterate for that value,
55+
if (inv[i] !== -1) {
56+
for (let k = 0; k < i; k++) {
57+
if (inv[i] - k < 0) break;
58+
dp[i][inv[i]] = (dp[i][inv[i]] + dp[i - 1][inv[i] - k]) % MOD;
59+
}
60+
}
61+
// case 2 when we don't have any given requirement
62+
// then iterate over all the values
63+
else {
64+
for (let c = 0; c <= m; c++) {
65+
// maximum number of inversions
66+
if (c > (i * (i - 1)) / 2) break;
67+
68+
for (let k = 0; k < i; k++) {
69+
if (c - k < 0) break;
70+
dp[i][c] = (dp[i][c] + dp[i - 1][c - k]) % MOD;
71+
}
72+
}
73+
}
74+
}
75+
76+
// return the ans
77+
return dp[n][inv[n]];
78+
};

0 commit comments

Comments
 (0)