Skip to content

Commit dd5163b

Browse files
authored
Merge pull request #2066 from Maheshwari-Love/add/solution-lc-3109
added solution for leetcode-3109
2 parents 9df1e22 + d1b2dfa commit dd5163b

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
---
2+
id: find-the-index-of-permutation
3+
title: 3109-Find the Index of Permutation
4+
sidebar_label: 3109 Find the Index of Permutation
5+
tags:
6+
- Array
7+
- Maths
8+
- LeetCode
9+
- C++
10+
description: "This is a solution to the Find the Index of Permutation problem on LeetCode."
11+
---
12+
13+
## Problem Description
14+
15+
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].
16+
17+
Since the answer may be very large, return it modulo 109 + 7.
18+
19+
### Examples
20+
21+
**Example 1:**
22+
23+
```
24+
Input: s = "cbadabacg", p = "abc"
25+
Output: 0
26+
Explanation: The first occurrence of a permutation of "abc" is "cba" which starts at index 0.
27+
28+
```
29+
30+
**Example 2:**
31+
32+
```
33+
Input: s = "eidbaooo", p = "ab"
34+
Output: 3
35+
Explanation: The first occurrence of a permutation of "ab" is "ba" which starts at index 3.
36+
37+
```
38+
39+
40+
### Constraints
41+
42+
- `1 <= n == perm.length <= 105`
43+
44+
45+
46+
### Approach
47+
According to the problem requirements, we need to find out how many permutations are lexicographically smaller than the given permutation.
48+
49+
We consider how to calculate the number of permutations that are lexicographically smaller than the given permutation. There are two situations:
50+
51+
- The first element of the permutation is less than $perm[0]$, there are $(perm[0] - 1) \times (n-1)!$ permutations.
52+
- The first element of the permutation is equal to $perm[0]$, we need to continue to consider the second element, and so on.
53+
- The sum of all situations is the answer.
54+
55+
We can use a binary indexed tree to maintain the number of elements that are smaller than the current element in the traversed elements. For the $i$-th element of the given permutation, the number of remaining elements that are smaller than it is $perm[i] - 1 - tree.query(perm[i])$, and the number of permutation types is $(perm[i] - 1 - tree.query(perm[i])) \times (n-i-1)!$, which is added to the answer. Then we update the binary indexed tree and add the current element to the binary indexed tree. Continue to traverse the next element until all elements are traversed.
56+
57+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Where $n$ is the length of the permutation.
58+
59+
#### Python3
60+
61+
```python
62+
class BinaryIndexedTree:
63+
__slots__ = "n", "c"
64+
65+
def __init__(self, n: int):
66+
self.n = n
67+
self.c = [0] * (n + 1)
68+
69+
def update(self, x: int, delta: int) -> None:
70+
while x <= self.n:
71+
self.c[x] += delta
72+
x += x & -x
73+
74+
def query(self, x: int) -> int:
75+
s = 0
76+
while x:
77+
s += self.c[x]
78+
x -= x & -x
79+
return s
80+
81+
82+
class Solution:
83+
def getPermutationIndex(self, perm: List[int]) -> int:
84+
mod = 10**9 + 7
85+
ans, n = 0, len(perm)
86+
tree = BinaryIndexedTree(n + 1)
87+
f = [1] * n
88+
for i in range(1, n):
89+
f[i] = f[i - 1] * i % mod
90+
for i, x in enumerate(perm):
91+
cnt = x - 1 - tree.query(x)
92+
ans += cnt * f[n - i - 1] % mod
93+
tree.update(x, 1)
94+
return ans % mod
95+
```
96+
97+
#### Java
98+
99+
```java
100+
class BinaryIndexedTree {
101+
private int n;
102+
private int[] c;
103+
104+
public BinaryIndexedTree(int n) {
105+
this.n = n;
106+
this.c = new int[n + 1];
107+
}
108+
109+
public void update(int x, int delta) {
110+
for (; x <= n; x += x & -x) {
111+
c[x] += delta;
112+
}
113+
}
114+
115+
public int query(int x) {
116+
int s = 0;
117+
for (; x > 0; x -= x & -x) {
118+
s += c[x];
119+
}
120+
return s;
121+
}
122+
}
123+
124+
class Solution {
125+
public int getPermutationIndex(int[] perm) {
126+
final int mod = (int) 1e9 + 7;
127+
long ans = 0;
128+
int n = perm.length;
129+
BinaryIndexedTree tree = new BinaryIndexedTree(n + 1);
130+
long[] f = new long[n];
131+
f[0] = 1;
132+
for (int i = 1; i < n; ++i) {
133+
f[i] = f[i - 1] * i % mod;
134+
}
135+
for (int i = 0; i < n; ++i) {
136+
int cnt = perm[i] - 1 - tree.query(perm[i]);
137+
ans = (ans + cnt * f[n - i - 1] % mod) % mod;
138+
tree.update(perm[i], 1);
139+
}
140+
return (int) ans;
141+
}
142+
}
143+
```

0 commit comments

Comments
 (0)