Given an array perm of length n which is a permutation of [1, 2, ..., n], return the index of perm in the lexicographically sorted array of all of the permutations of [1, 2, ..., n].
Since the answer may be very large, return it modulo109 + 7.
Input: perm =[1,2]Output: 0Explanation:
There are only two permutations in the following order:`[1,2]`,`[2,1]`And `[1,2]`is at index 0.
Example 2:
1
2
3
4
5
6
Input: perm =[3,1,2]Output: 4Explanation:
There are only six permutations in the following order:`[1,2,3]`,`[1,3,2]`,`[2,1,3]`,`[2,3,1]`,`[3,1,2]`,`[3,2,1]`And `[3,1,2]`is at index 4.
The index of a permutation in lexicographical order can be found by counting, for each position, how many smaller numbers remain to the right. This is efficiently computed using the factorial number system (Lehmer code) and a Fenwick Tree (BIT) for fast prefix sums.
classSolution {
public:int findPermutationIndex(vector<int>& perm) {
constint MOD =1e9+7;
int n = perm.size();
vector<int> bit(n+2, 0);
auto add = [&](int x) { for (; x <= n; x += x &-x) bit[x] +=1; };
auto sum = [&](int x) { int s =0; for (; x; x -= x &-x) s += bit[x]; return s; };
vector<longlong> fact(n+1, 1);
for (int i =1; i <= n; ++i) fact[i] = fact[i-1] * i % MOD;
int idx =0;
for (int i =0; i < n; ++i) {
int cnt = perm[i] -1- sum(perm[i] -1);
idx = (idx +1LL* cnt * fact[n-1-i] % MOD) % MOD;
add(perm[i]);
}
return (idx +1) % MOD;
}
};
classSolution {
publicintfindPermutationIndex(int[] perm) {
int MOD = 1_000_000_007, n = perm.length;
int[] bit =newint[n+2];
java.util.function.IntConsumer add = x -> { for (; x <= n; x += x &-x) bit[x]++; };
java.util.function.IntUnaryOperator sum = x -> { int s = 0; for (; x > 0; x -= x &-x) s += bit[x]; return s; };
long[] fact =newlong[n+1];
fact[0]= 1;
for (int i = 1; i <= n; i++) fact[i]= fact[i-1]* i % MOD;
int idx = 0;
for (int i = 0; i < n; i++) {
int cnt = perm[i]- 1 - sum.applyAsInt(perm[i]-1);
idx = (int)((idx + cnt * fact[n-1-i]% MOD) % MOD);
add.accept(perm[i]);
}
return (idx + 1) % MOD;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
funfindPermutationIndex(perm: IntArray): Int {
val MOD = 1_000_000_007
val n = perm.size
val bit = IntArray(n+2)
funadd(x: Int) { var x = x; while (x <= n) { bit[x]++; x += x and -x } }
funsum(x: Int): Int { var x = x; var s = 0; while (x > 0) { s += bit[x]; x -= x and -x }; return s }
val fact = LongArray(n+1) { 1L }
for (i in1..n) fact[i] = fact[i-1] * i % MOD
var idx = 0Lfor (i in0 until n) {
val cnt = perm[i] - 1 - sum(perm[i]-1)
idx = (idx + cnt * fact[n-1-i] % MOD) % MOD
add(perm[i])
}
return ((idx + 1) % MOD).toInt()
}
}
classSolution:
deffindPermutationIndex(self, perm: list[int]) -> int:
MOD =10**9+7 n = len(perm)
fact = [1] * (n+1)
for i in range(1, n+1):
fact[i] = fact[i-1] * i % MOD
bit = [0] * (n+2)
defadd(x):
while x <= n:
bit[x] +=1 x += x &-x
defquery(x):
s =0while x:
s += bit[x]
x -= x &-x
return s
idx =0for i in range(n):
cnt = perm[i] -1- query(perm[i]-1)
idx = (idx + cnt * fact[n-1-i]) % MOD
add(perm[i])
return (idx +1) % MOD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
impl Solution {
pubfnfind_permutation_index(perm: Vec<i32>) -> i32 {
constMOD: i64=1_000_000_007;
let n = perm.len();
letmut fact =vec![1i64; n+1];
for i in1..=n { fact[i] = fact[i-1] * i asi64%MOD; }
letmut bit =vec![0; n+2];
letmut add =|mut x: usize| { while x <= n { bit[x] +=1; x += x & (!x +1); } };
letmut sum =|mut x: usize| { letmut s =0; while x >0 { s += bit[x]; x -= x & (!x +1); } s };
letmut idx =0i64;
for i in0..n {
let cnt = perm[i] asusize-1- sum(perm[i] asusize-1);
idx = (idx + cnt asi64* fact[n-1-i] %MOD) %MOD;
add(perm[i] asusize);
}
((idx +1) %MOD) asi32 }
}