Skip to content
geeksforgeeks
  • Tutorials
    • Python
    • Java
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
    • Practice Coding Problems
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • DSA
  • Interview Problems on DP
  • Practice DP
  • MCQs on DP
  • Tutorial on Dynamic Programming
  • Optimal Substructure
  • Overlapping Subproblem
  • Memoization
  • Tabulation
  • Tabulation vs Memoization
  • 0/1 Knapsack
  • Unbounded Knapsack
  • Subset Sum
  • LCS
  • LIS
  • Coin Change
  • Word Break
  • Egg Dropping Puzzle
  • Matrix Chain Multiplication
  • Palindrome Partitioning
  • DP on Arrays
  • DP with Bitmasking
  • Digit DP
  • DP on Trees
  • DP on Graph
Open In App
Next Article:
Number of permutation with K inversions
Next article icon

Number of permutation with K inversions

Last Updated : 08 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report
Try it on GfG Practice
redirect icon

We are given two numbers n and k, the task is to find how many permutations of the first n number have exactly k inversion. Two elements in a sequence form an inversion if the smaller element appears before the larger element.

Examples: 

Input: n = 3, k = 1
Output: 2
Explanation: Total Permutation of first 3 numbers are 123, 132, 213, 231, 312, 321
Permutation with 1 inversion: 132 and 213

Input: n = 3, k = 3
Output: 1
Explanation: Permutation with 3 inversions: 321

Table of Content

  • Using Recursion - O(n! * k) Time and O(n) Space
  • Using Top-Down DP (Memoization) – O(n*k*k) Time and O(n*k) Space
  • Using Bottom-Up DP (Tabulation) – O(n*k*k) Time and O(n*k) Space

Using Recursion - O(n! * k) Time and O(n) Space

Base Cases:

  • If n == 0, no permutations are possible, so return 0.
  • If k == 0, there is exactly one permutation (the sorted order), so return 1.

Recursive Relation:

  • For each possible position i where the nth element can be placed (where i ranges from 0 to min(k, n-1)), we recursively call the function to calculate the number of permutations of n-1 elements with k-i inversions. This represents placing the nth element in a way that creates i inversions.

countPermWithkInversions(n, k) = Σ(countPermWithkInversions(n-1, k-i)) for i = 0 to min(k, n-1)

C++
// C++ code to count permutations with exactly // k inversions using Recursion #include <iostream> using namespace std;  int countPermWithkInversions(int n, int k) {        // Base cases     // no permutations possible with 0 elements     if (n == 0) return 0;           // Only one way to have 0 inversions: sorted order     if (k == 0) return 1;           // Initialize result for this recursive step     int result = 0;      // Recursively sum up all valid counts      // by placing the nth largest element     // in positions that create the      // required inversion counts     for (int i = 0; i <= min(k, n - 1); i++) {         result += countPermWithkInversions(n - 1, k - i);     }      return result; }  int main() {        int n = 4;      int k = 2;       cout << countPermWithkInversions(n, k);      return 0; } 
Java
// Java code to count permutations with  // exactly k inversions using Recursion class GfG {      static int countPermWithkInversions(int n, int k) {          // Base cases         // no permutations possible with 0 elements         if (n == 0) return 0;          // Only one way to have 0 inversions: sorted order         if (k == 0) return 1;          // Initialize result for this recursive step         int result = 0;          // Recursively sum up all valid counts         // by placing the nth largest element         // in positions that create the         // required inversion counts         for (int i = 0; i <= Math.min(k, n - 1); i++) {             result += countPermWithkInversions(n - 1, k - i);         }          return result;     }      public static void main(String[] args) {          int n = 4;         int k = 2;          System.out.println(countPermWithkInversions(n, k));     } } 
Python
# Python code to count permutations with exactly # k inversions using Recursion def countPermWithkInversions(n, k):      # Base cases     # no permutations possible with 0 elements     if n == 0:         return 0      # Only one way to have 0 inversions: sorted order     if k == 0:         return 1      # Initialize result for this recursive step     result = 0      # Recursively sum up all valid counts     # by placing the nth largest element     # in positions that create the     # required inversion counts     for i in range(min(k, n - 1) + 1):         result += countPermWithkInversions(n - 1, k - i)      return result    if __name__ == "__main__":        n = 4     k = 2      print(countPermWithkInversions(n, k)) 
C#
// C# code  to count permutations with exactly  // k inversions using Recursion using System;  class GfG {      static int countPermWithkInversions(int n, int k) {          // Base cases         // no permutations possible with 0 elements         if (n == 0) return 0;          // Only one way to have 0 inversions: sorted order         if (k == 0) return 1;          // Initialize result for this recursive step         int result = 0;          // Recursively sum up all valid counts         // by placing the nth largest element         // in positions that create the         // required inversion counts         for (int i = 0; i <= Math.Min(k, n - 1); i++) {             result += countPermWithkInversions(n - 1, k - i);         }          return result;     }      static void Main() {         int n = 4;         int k = 2;          Console.WriteLine(countPermWithkInversions(n, k));     } } 
JavaScript
// Javascript code to  count permutations with  // exactly k inversions using Recursion function countPermWithkInversions(n, k) {      // Base cases     // no permutations possible with 0 elements     if (n === 0) return 0;      // Only one way to have 0 inversions: sorted order     if (k === 0) return 1;      // Initialize result for this recursive step     let result = 0;      // Recursively sum up all valid counts     // by placing the nth largest element     // in positions that create the     // required inversion counts     for (let i = 0; i <= Math.min(k, n - 1); i++) {         result += countPermWithkInversions(n - 1, k - i);     }      return result; }  const n = 4; const k = 2;  console.log(countPermWithkInversions(n, k)); 

Output
5

Using Top-Down DP (Memoization) – O(n*k*k) Time and O(n*k) Space

The above recursive solution satisfies two key properties of Dynamic Programming, enabling us to use memoization for an optimized approach.

1. Optimal Substructure

We solve the problem of counting permutations with exactly k inversions by breaking it into subproblems involving fewer elements and inversions. Specifically, if we have n elements and k required inversions, we can compute it by trying positions for the largest element in a way that contributes to the inversion count.

The recursive relation is:

  • countPermWithkInversions(n, k) = Σ countPermWithkInversions(n-1, k-i)

Here, we consider placing the largest element in positions that create i inversions, where i ranges from 0 to min(k, n-1).

2. Overlapping Subproblems:

Many subproblems are computed multiple times when finding permutations for smaller subsets and inversion counts. For example, while calculating the result for (n, k), subproblems for (n-1, k-i) are encountered repeatedly.

We use a 2D array memo of size (n+1) x (k+1), initialized to -1, to store results of subproblems. If a result is already stored in memo[n][k], we return it directly, avoiding redundant calculations.

C++
// C++ code to find number of permutation  // with k inversion using Memoization #include <bits/stdc++.h> using namespace std;  // Helper function for recursive computation int kInversionsHelper(int n, int k,                       vector<vector<int>>& memo) {        // Base case: If there are no elements,     // no permutations are possible     if (n == 0) return 0;      // Base case: If k is 0, only one way to      // have 0 inversions: sorted order     if (k == 0) return 1;      // Check if the result is already      // computed (memoization)     if (memo[n][k] != -1) return memo[n][k];      int result = 0;      // Loop through possible inversion counts      // for the nth largest element     for (int i = 0; i <= min(k, n - 1); i++) {                // Recursively count permutations for the          // remaining elements and inversions         result = (result +               kInversionsHelper(n - 1, k - i, memo));     }      return memo[n][k] = result; }  // Function to count permutations with k inversions int countPermWithkInversions(int n, int k) {        // Initialize memoization table with -1      // to indicate uncomputed values     vector<vector<int>> memo(n + 1, vector<int>(k + 1, -1));        return kInversionsHelper(n, k, memo); }  int main() {        int n = 4;     int k = 2;       cout << countPermWithkInversions(n, k);      return 0; } 
Java
// Java code to find number of permutation  // with k inversions using Memoization import java.util.Arrays;  class GfG {      // Helper function for recursive computation     static int kInversionsHelper(int n, int k, int[][] memo) {                  // Base case: If there are no elements,         // no permutations are possible         if (n == 0) return 0;          // Base case: If k is 0, only one way to          // have 0 inversions: sorted order         if (k == 0) return 1;          // Check if the result is already          // computed (memoization)         if (memo[n][k] != -1) return memo[n][k];          int result = 0;          // Loop through possible inversion counts          // for the nth largest element         for (int i = 0; i <= Math.min(k, n - 1); i++) {                        // Recursively count permutations for the              // remaining elements and inversions             result = (result                  + kInversionsHelper(n - 1, k - i, memo));         }          return memo[n][k] = result;     }      // Function to count permutations with k inversions     static int countPermWithkInversions(int n, int k) {                  // Initialize memoization table with -1          // to indicate uncomputed values         int[][] memo = new int[n + 1][k + 1];         for (int[] row : memo) {             Arrays.fill(row, -1);         }                  return kInversionsHelper(n, k, memo);     }      public static void main(String[] args) {                  int n = 4;         int k = 2;           System.out.println(countPermWithkInversions(n, k));     } } 
Python
# Python code to find number of permutation  # with k inversions using Memoization  def kInversionsHelper(n, k, memo):        # Base case: If there are no elements,     # no permutations are possible     if n == 0:         return 0      # Base case: If k is 0, only one way to      # have 0 inversions: sorted order     if k == 0:         return 1      # Check if the result is already      # computed (memoization)     if memo[n][k] != -1:         return memo[n][k]      result = 0      # Loop through possible inversion counts      # for the nth largest element     for i in range(min(k, n - 1) + 1):                # Recursively count permutations for the          # remaining elements and inversions         result = (result + kInversionsHelper(n - 1, k - i, memo))      memo[n][k] = result     return result  def countPermWithkInversions(n, k):        # Initialize memoization table with -1      # to indicate uncomputed values     memo = [[-1 for _ in range(k + 1)] for _ in range(n + 1)]     return kInversionsHelper(n, k, memo)  if __name__ == "__main__":        n = 4     k = 2       print(countPermWithkInversions(n, k)) 
C#
// C# code to find number of permutation  // with k inversions using Memoization using System;  class GfG {          // Helper function for recursive computation    	static int kInversionsHelper(int n, int k, int[,] memo) {                  // Base case: If there are no elements,         // no permutations are possible         if (n == 0) return 0;          // Base case: If k is 0, only one way to          // have 0 inversions: sorted order         if (k == 0) return 1;          // Check if the result is already          // computed (memoization)         if (memo[n, k] != -1) return memo[n, k];          int result = 0;          // Loop through possible inversion counts          // for the nth largest element         for (int i = 0; i <= Math.Min(k, n - 1); i++) {                        // Recursively count permutations for the              // remaining elements and inversions             result = (result + kInversionsHelper(n - 1, k - i, memo));         }          return memo[n, k] = result;     }      static int countPermWithkInversions(int n, int k) {                  // Initialize memoization table with -1          // to indicate uncomputed values         int[,] memo = new int[n + 1, k + 1];         for (int i = 0; i < memo.GetLength(0); i++) {             for (int j = 0; j < memo.GetLength(1); j++) {                 memo[i, j] = -1;             }         }          return kInversionsHelper(n, k, memo);     }      static void Main() {                  int n = 4;         int k = 2;           Console.WriteLine(countPermWithkInversions(n, k));     } } 
JavaScript
// JavaScript code to find number of permutation // with k inversions using Memoization  function kInversionsHelper(n, k, memo) {      // Base case: If there are no elements,     // no permutations are possible     if (n === 0)         return 0;      // Base case: If k is 0, only one way to     // have 0 inversions: sorted order     if (k === 0)         return 1;      // Check if the result is already     // computed (memoization)     if (memo[n][k] !== -1)         return memo[n][k];      let result = 0;      // Loop through possible inversion counts     // for the nth largest element     for (let i = 0; i <= Math.min(k, n - 1); i++) {          // Recursively count permutations for the         // remaining elements and inversions         result = (result                   + kInversionsHelper(n - 1, k - i, memo));     }      memo[n][k] = result;     return result; }  function countPermWithkInversions(n, k) {      // Initialize memoization table with -1     // to indicate uncomputed values     const memo = Array.from({length : n + 1},                             () => Array(k + 1).fill(-1));     return kInversionsHelper(n, k, memo); }  const n = 4; const k = 2;  console.log(countPermWithkInversions(n, k)); 

Output
5

Using Bottom-Up DP (Tabulation) – O(n*k*k) Time and O(n*k) Space

We create a 2D array dp of size (n + 1)*(k + 1), where the state dp[l][r] represents the number of permutations of l elements with exactly r inversions.

Base Case: dp[l][0] = 1 for all l, since there's only one way to have zero inversions-by arranging elements in sorted order.

For each element count l from 1 to n:

  • For each inversion count r from 1 to k, calculate the number of valid permutations.
  • To compute dp[l][r], we iterate over all possible positions of the largest element, which can create up to min(r, l-1) inversions, summing up the results from previous states

This relation fills the DP table by counting valid permutations based on subproblems:

  • dp[l][r] = sum of dp[l-1][r-i] for all valid i.

The final result is stored in dp[n][k], representing the total permutations of n elements with exactly k inversions.

C++
// C++ code to find number of permutation  // with K inversions using Tabulation #include <bits/stdc++.h> using namespace std;  int countPermWithkInversions(int n, int k) {        // Initialize a 2D table for dynamic programming     vector<vector<int>> dp(n + 1, vector<int>(k + 1, 0));      // Base case: If k is 0, only one way to      // have 0 inversions: sorted order     for (int l = 0; l <= n; l++) {         dp[l][0] = 1;     }      // Fill the table using the tabulation method     for (int l = 1; l <= n; l++) {         for (int r = 1; r <= k; r++) {             for (int i = 0; i <= min(r, l - 1); i++) {                                // Count permutations for the remaining                  // elements and inversions                 dp[l][r] = (dp[l][r] + dp[l - 1][r - i]);             }         }     }      return dp[n][k]; }  int main() {      int n = 4;     int k = 2;       cout << countPermWithkInversions(n, k);      return 0; } 
Java
// Java code to find number of permutation  // with K inversions using Tabulation import java.util.Arrays;  class GfG {     static int countPermWithkInversions(int n, int k) {                // Initialize a 2D table for dynamic programming         int[][] dp = new int[n + 1][k + 1];          // Base case: If k is 0, only one way to          // have 0 inversions: sorted order         for (int l = 0; l <= n; l++) {             dp[l][0] = 1;         }          // Fill the table using the tabulation method         for (int l = 1; l <= n; l++) {             for (int r = 1; r <= k; r++) {                 for (int i = 0; i <= Math.min(r, l - 1); i++) {                                        // Count permutations for the remaining                      // elements and inversions                     dp[l][r] = (dp[l][r] + dp[l - 1][r - i]);                 }             }         }          return dp[n][k];     }      public static void main(String[] args) {                int n = 4;         int k = 2;           System.out.println(countPermWithkInversions(n, k));     } } 
Python
# Python code to find number of permutation  # with k inversions using Tabulation  def countPermWithkInversions(n, k):        # Initialize a 2D table for dynamic programming     dp = [[0] * (k + 1) for _ in range(n + 1)]      # Base case: If k is 0, only one way to      # have 0 inversions: sorted order     for l in range(n + 1):         dp[l][0] = 1      # Fill the table using the tabulation method     for l in range(1, n + 1):         for r in range(1, k + 1):             for i in range(min(r, l - 1) + 1):                                # Count permutations for the remaining                  # elements and inversions                 dp[l][r] = (dp[l][r] + dp[l - 1][r - i])      return dp[n][k]    if __name__ == "__main__":      n = 4     k = 2       print(countPermWithkInversions(n, k)) 
C#
// C# code to find number of permutation  // with k inversions using Tabulation using System;  class GfG {     static int countPermWithkInversions(int n, int k) {                // Initialize a 2D table for dynamic programming         int[,] dp = new int[n + 1, k + 1];          // Base case: If k is 0, only one way to          // have 0 inversions: sorted order         for (int l = 0; l <= n; l++) {             dp[l, 0] = 1;         }          // Fill the table using the tabulation method         for (int l = 1; l <= n; l++) {             for (int r = 1; r <= k; r++) {                 for (int i = 0; i <= Math.Min(r, l - 1); i++) {                                        // Count permutations for the remaining                      // elements and inversions                     dp[l, r] = (dp[l, r] + dp[l - 1, r - i]);                 }             }         }          return dp[n, k];     }      static void Main() {                int n = 4;         int k = 2;           Console.WriteLine(countPermWithkInversions(n, k));     } } 
JavaScript
// JavaScript code to find number of permutation  // with k inversions using Tabulation  function countPermWithkInversions(n, k) {      // Initialize a 2D table for dynamic programming     const dp = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0));      // Base case: If k is 0, only one way to      // have 0 inversions: sorted order     for (let l = 0; l <= n; l++) {         dp[l][0] = 1;     }      // Fill the table using the tabulation method     for (let l = 1; l <= n; l++) {         for (let r = 1; r <= k; r++) {             for (let i = 0; i <= Math.min(r, l - 1); i++) {                              // Count permutations for the remaining                  // elements and inversions                 dp[l][r] = (dp[l][r] + dp[l - 1][r - i]);             }         }     }      return dp[n][k]; }  let n = 4; let k = 2;  console.log(countPermWithkInversions(n, k)); 

Output
5

Time Complexity: O(n*k*k), where n is the number of elements and k is the number of inversions, due to the nested loops iterating through n, k, and possible inversions.
Auxiliary Space: O(n*k), because we maintain a 2D table of size (n+1)×(k+1) to store the computed values for dynamic programming.


Next Article
Number of permutation with K inversions

U

Utkarsh Trivedi and Ankit Kumar Sharma
Improve
Article Tags :
  • Dynamic Programming
  • DSA
  • permutation
  • inversion
Practice Tags :
  • Dynamic Programming
  • permutation

Similar Reads

    Number of permutation with K inversions | Set 2
    Given two integers N and K, the task is to count the number of permutations of the first N natural numbers having exactly K inversions. Since the count can be very large, print it modulo 109 + 7. An inversion is defined as a pair a[i], a[j] such that a[i] > a[j] and i < j. Examples: Input: N =
    8 min read
    Find a permutation of N natural numbers with K inversions
    Given two integers N and K, the task is to find a permutation of first N natural numbers with exactly K inversions. Examples : Input: N = 5, K = 4Output: 5 1 2 3 4 Explanation: In the above permutation P, the pairs (i, j) such that i < j and P[i] > P[j] are (0, 1), (0, 2), (0, 3), and (0, 4).
    9 min read
    Find the number of good permutations
    Given two integers N and K. The task is to find the number of good permutations of the first N natural numbers. A permutation is called good if there exist at least N - K indices i (1 ? i ? N) such that Pi = i. Examples: Input: N = 4, K = 1 Output: 1 {1, 2, 3, 4} is the only possible good permutatio
    6 min read
    Distinct permutations of a number
    Given an integer N, the task is to print all distinct permutations of the number N. Examples: Input: N = 133Output: 133 313 331Explanation:There are a total of 6 permutations, which are [133, 313, 331, 133, 313, 331].Out of all these permutations, distinct permutations are [133, 313, 331]. Input: N
    9 min read
    Count the number of special permutations
    Given two positive integers n and k, the task is to count the number of special permutations. A special permutation P is defined as a permutation of first n natural numbers in which there exists at least (n - k) indices such that Pi = i. Prerequisite: Derangements Examples: Input: n = 4, k = 2 Outpu
    15+ min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences