Problem Description
Given a permutation array perm of length n (which is a permutation of [1, 2, ..., n]), the task is to return the index (0-indexed) of the given permutation in the lexicographically sorted list of all permutations. Since the answer may be very large, return it modulo (10^9 + 7).
Example 1: Input: perm = [1,2] Output: 0 Explanation: The lexicographically sorted list of permutations is [ [1,2], [2,1] ] and [1,2] appears at index 0.
Example 2: Input: perm = [3,1,2] Output: 4 Explanation: The lexicographically sorted list of permutations is [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] and [3,1,2] appears at index 4.
Key Insights
- The lexicographic rank of a permutation can be determined by counting how many permutations would come before it.
- For every position in the permutation, count the number of unused numbers smaller than the current number.
- Multiply this count by the factorial of the number of remaining positions.
- Use a data structure like a Binary Indexed Tree (Fenwick Tree) to efficiently count the number of unused numbers smaller than a given value.
- Precompute factorials mod (10^9+7) to avoid recomputation and to handle the large numbers under modulo arithmetic.
Space and Time Complexity
Time Complexity: O(n log n) – O(n) iterations each doing BIT (Fenwick tree) operations in O(log n).
Space Complexity: O(n) – for the BIT and factorial precomputation arrays.
Solution
We first precompute factorials modulo (10^9+7) for numbers from 0 to n. Then, we initialize a Binary Indexed Tree (BIT) that keeps track of which numbers are still unused (initially every number from 1 to n is available). For each element in the permutation:
- Query the BIT to determine how many numbers less than the current element are still available.
- The contribution of the current element is (number of such unused numbers) * factorial(remaining positions) modulo (10^9+7).
- Update the BIT to mark the current element as used.
- Sum up all contributions to obtain the lexicographic index. This approach efficiently handles the computation even for large n.