Watch 4 video solutions for Count the Number of Inversions, a hard level problem involving Array, Dynamic Programming. This walkthrough by Aryan Mittal has 6,349 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
You are given an integer n and a 2D array requirements, where requirements[i] = [endi, cnti] represents the end index and the inversion count of each requirement.
A pair of indices (i, j) from an integer array nums is called an inversion if:
i < j and nums[i] > nums[j]Return the number of permutations perm of [0, 1, 2, ..., n - 1] such that for all requirements[i], perm[0..endi] has exactly cnti inversions.
Since the answer may be very large, return it modulo 109 + 7.
Example 1:
Input: n = 3, requirements = [[2,2],[0,0]]
Output: 2
Explanation:
The two permutations are:
[2, 0, 1]
[2, 0, 1] has inversions (0, 1) and (0, 2).[2] has 0 inversions.[1, 2, 0]
[1, 2, 0] has inversions (0, 2) and (1, 2).[1] has 0 inversions.Example 2:
Input: n = 3, requirements = [[2,2],[1,1],[0,0]]
Output: 1
Explanation:
The only satisfying permutation is [2, 0, 1]:
[2, 0, 1] has inversions (0, 1) and (0, 2).[2, 0] has an inversion (0, 1).[2] has 0 inversions.Example 3:
Input: n = 2, requirements = [[0,0],[1,0]]
Output: 1
Explanation:
The only satisfying permutation is [0, 1]:
[0] has 0 inversions.[0, 1] has an inversion (0, 1).
Constraints:
2 <= n <= 3001 <= requirements.length <= nrequirements[i] = [endi, cnti]0 <= endi <= n - 10 <= cnti <= 400i such that endi == n - 1.endi are unique.Problem Overview: You are given constraints about inversion counts in permutations. An inversion is a pair (i, j) where i < j and nums[i] > nums[j]. The task is to count how many valid permutations satisfy the required inversion conditions.
Approach 1: Brute Force Permutation Enumeration (O(n! * n), O(n))
Generate every permutation of the numbers 1..n. For each permutation, iterate through all index pairs and count inversions. After computing the inversion count, verify whether it satisfies the required condition. This approach is straightforward but infeasible beyond very small n because generating permutations costs O(n!) time. It mainly helps build intuition about how inversion counts behave in permutations.
Approach 2: Dynamic Programming on Permutation Size (O(n * k), O(n * k))
The key insight: when inserting the next largest number into a permutation, you control how many new inversions it creates. Define dp[i][j] as the number of permutations of length i that contain exactly j inversions. When placing the element i, it can be inserted in any of the i positions. Inserting it near the front adds more inversions, while inserting near the end adds fewer. The transition becomes dp[i][j] = sum(dp[i-1][j-x]) for all valid x positions where 0 ≤ x < i. This builds permutations incrementally while tracking inversion counts.
To make this efficient, compute transitions using prefix sums so each state can be calculated in constant time instead of iterating through all insertion positions. This reduces the complexity from O(n * k * n) to O(n * k). The DP table effectively enumerates all possible ways to distribute inversions across permutation sizes.
The constraints in the problem restrict which inversion counts are allowed for specific prefixes. While filling the DP table, you simply zero out states that violate those constraints. This filtering ensures that only permutations meeting all requirements remain counted.
This solution combines classic permutation inversion DP with constraint filtering. The reasoning heavily relies on understanding how inversions change when inserting elements into a sequence. Problems involving permutation structure and inversion counts often fall under Dynamic Programming combined with careful reasoning on Array positions and prefix properties.
Recommended for interviews: The dynamic programming approach with prefix-sum optimization is the expected solution. Brute force permutation generation demonstrates understanding of inversion definitions, but the DP formulation shows algorithmic maturity and the ability to optimize combinatorial counting problems.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Permutations | O(n! * n) | O(n) | Small n or for understanding inversion counting logic |
| Dynamic Programming (Basic Transition) | O(n * k * n) | O(n * k) | When implementing the straightforward DP relation for inversion insertion |
| Dynamic Programming with Prefix Sum Optimization | O(n * k) | O(n * k) | Optimal solution for large constraints and typical interview expectations |