Open In App

Count permutations of 0 to N-1 with at least K elements same as positions

Improve
Improve
Like Article
Like
Save
Share
Report

Given two integers, N and K, the task is to find the number of permutations of numbers from 0 to N – 1, such that there are at least K positions in the array such that arr[i] = i ( 0 <= i < N ). As the answer can be very large, calculate the result modulo 10^9+7.

Examples:

Input: N = 4,  K = 3  
Output: 1
Explanation: There is only one permutation [0, 1, 2, 3] such that number of elements with arr[i] = i is K = 3.

Input: N = 4, K = 2
Output: 7
Explanation: There are 7 permutations satisfying the condition which are as follow:

  1. [0, 1, 2, 3]
  2. [0, 1, 3, 2]
  3. [0, 3, 2, 1]
  4. [0, 2, 1, 3]
  5. [3, 1, 2, 0]
  6. [2, 1, 0, 3]
  7. [1, 0, 2, 3]
 

Naive approach: The basic idea to solve the problem is to firstly find the Permutation of array.

Follow the steps to solve the problem:

  • Recursively find all possible permutations and then,
  • Check for each of them whether it is following the condition or not.
  • Maintain a counter based on that and increment it when the current permutation satisfies the condition.

Below is the implementation of the above approach :

C++




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// Recursive function to get the
// all permutations of current array
void getPermutations(vector<int>& arr,
                     int index, int k,
                     int& ans)
{
 
    // Base condition if current index is
    // greater than or equal to array size
 
    if (index >= arr.size()) {
 
        // Initialising the variable count
        int count = 0;
 
        // Counting the number of positions
        // with arr[i] = i in the array
        for (int i = 0; i < arr.size(); i++) {
            if (arr[i] == i) {
                count++;
            }
        }
 
        // If count is greater than
        // or equal to k then
        // increment the ans
        if (count >= k) {
            ans++;
        }
 
        return;
    }
 
    // Iterating over the array arr
    for (int i = index; i < arr.size(); i++) {
 
        // Swapping current index with I
        swap(arr[index], arr[i]);
 
        // Calling recursion for current
        // condition
        getPermutations(arr, index + 1, k, ans);
 
        // Resetting the swapped position.
        swap(arr[index], arr[i]);
    }
}
 
int numberOfPermutations(long long n,
                         long long k)
{
 
    // Initializing the variables
    //'mod' and 'ans'.
    int mod = 1e9 + 7;
    int ans = 0;
 
    // Initializing the array 'arr'.
    vector<int> arr;
 
    // Pushing numbers in the array.
    for (int i = 0; i < n; i++) {
        arr.push_back(i);
    }
 
    // Calling recursive function 'getPermutations'
    getPermutations(arr, 0, k, ans);
 
    // Returning 'ans'.
    return ans % mod;
}
 
// Driver Code
int main()
{
    long long N = 4;
    long long K = 2;
    cout << numberOfPermutations(N, K);
    return 0;
}


Java




// Java code for the above approach:
import java.util.*;
 
class GFG {
 
  static int ans = 0;
   
  // Recursive function to get the
  // all permutations of current array
  static void getPermutations(Vector<Integer> arr,
                              int index, long k)
  {
 
    // Base condition if current index is
    // greater than or equal to array size
 
    if (index >= arr.size()) {
 
      // Initialising the variable count
      int count = 0;
 
      // Counting the number of positions
      // with arr[i] = i in the array
      for (int i = 0; i < arr.size(); i++) {
        if (arr.get(i) == i) {
          count++;
        }
      }
 
      // If count is greater than
      // or equal to k then
      // increment the ans
      if (count >= k) {
        ans++;
      }
 
      return;
    }
 
    // Iterating over the array arr
    for (int i = index; i < arr.size(); i++) {
 
      // Swapping current index with I
      int temp = arr.get(index);
      arr.set(index, arr.get(i));
      arr.set(i, temp);
      // Calling recursion for current
      // condition
      getPermutations(arr, index + 1, k);
 
      // Resetting the swapped position.
      temp = arr.get(index);
      arr.set(index, arr.get(i));
      arr.set(i, temp);
    }
  }
 
  static int numberOfPermutations(long n,
                                  long k)
  {
 
    // Initializing the variables
    //'mod' and 'ans'.
    int mod = 1000000000 + 7;
 
 
    // Initializing the array 'arr'.
    Vector<Integer> arr = new Vector<Integer>();
 
    // Pushing numbers in the array.
    for (int i = 0; i < n; i++) {
      arr.add(i);
    }
 
    // Calling recursive function 'getPermutations'
    getPermutations(arr, 0, k);
 
    // Returning 'ans'.
    return ans % mod;
  }
 
  // Driver Code
  public static void main (String[] args) {
    long N = 4;
    long K = 2;
    System.out.println(numberOfPermutations(N, K));
  }
}
 
// This code is contributed by hrithikgarg03188.


Python3




# Python code for the approach
 
# Recursive function to get the
# all permutations of current array
ans = 0
 
def getPermutations(arr, index, k):
    global ans
     
    # Base condition if current index is
    # greater than or equal to array size
    if (index >= len(arr)):
 
        # Initialising the variable count
        count = 0
 
        # Counting the number of positions
        # with arr[i] = i in the array
        for i in range(len(arr)):
            if (arr[i] == i):
                count += 1
 
        # If count is greater than
        # or equal to k then
        # increment the ans
        if (count >= k):
            ans += 1
 
        return
 
    # Iterating over the array arr
    for i in range(index, len(arr)):
 
        # Swapping current index with I
        temp = arr[index]
        arr[index] = arr[i]
        arr[i] = temp
         
        # Calling recursion for current
        # condition
        getPermutations(arr, index + 1, k)
 
        # Resetting the swapped position.
        temp = arr[index]
        arr[index] = arr[i]
        arr[i] = temp
     
def numberOfPermutations(n, k):
 
    # Initializing the variables
    #'mod' and 'ans'.
    mod = 1e9 + 7
 
    # Initializing the array 'arr'.
    arr = []
 
    # Pushing numbers in the array.
    for i in range(n):
        arr.append(i)
 
    # Calling recursive function 'getPermutations'
    getPermutations(arr, 0, k)
 
    # Returning 'ans'.
    return int(ans % mod)
 
# Driver Code
 
N = 4
K = 2
print(numberOfPermutations(N, K))
 
# This code is contributed by shinjanpatra


C#




// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
 
class GFG
{
 
  static int ans = 0;
 
  // Recursive function to get the
  // all permutations of current array
  static void getPermutations(List<int> arr,
                              int index, long k)
  {
 
    // Base condition if current index is
    // greater than or equal to array size
 
    if (index >= arr.Count) {
 
      // Initialising the variable count
      int count = 0;
 
      // Counting the number of positions
      // with arr[i] = i in the array
      for (int i = 0; i < arr.Count; i++) {
        if (arr[i] == i) {
          count++;
        }
      }
 
      // If count is greater than
      // or equal to k then
      // increment the ans
      if (count >= k) {
        ans++;
      }
 
      return;
    }
 
    // Iterating over the array arr
    for (int i = index; i < arr.Count; i++) {
 
      // Swapping current index with I
      int temp = arr[index];
      arr[index] = arr[i];
      arr[i] = temp;
      // Calling recursion for current
      // condition
      getPermutations(arr, index + 1, k);
 
      // Resetting the swapped position.
      temp = arr[index];
      arr[index] = arr[i];
      arr[i] = temp;
    }
  }
 
  static int numberOfPermutations(long n,
                                  long k)
  {
 
    // Initializing the variables
    //'mod' and 'ans'.
    int mod = 1000000000 + 7;
 
 
    // Initializing the array 'arr'.
    List<int> arr = new List<int>();
 
    // Pushing numbers in the array.
    for (int i = 0; i < n; i++) {
      arr.Add(i);
    }
 
    // Calling recursive function 'getPermutations'
    getPermutations(arr, 0, k);
 
    // Returning 'ans'.
    return ans % mod;
  }
 
  // Driver Code
  public static void Main()
  {
    long N = 4;
    long K = 2;
    Console.Write(numberOfPermutations(N, K));
  }
}
 
// This code is contributed by code_hunt.


Javascript




<script>
// Recursive function to get the
// all permutations of current array
let ans = 0;
 
function getPermutations(arr, index, k)
{
 
    // Base condition if current index is
    // greater than or equal to array size
    if (index >= arr.length) {
 
        // Initialising the variable count
        let count = 0;
 
        // Counting the number of positions
        // with arr[i] = i in the array
        for (let i = 0; i < arr.length; i++) {
            if (arr[i] == i) {
                count++;
            }
        }
 
        // If count is greater than
        // or equal to k then
        // increment the ans
        if (count >= k) {
            ans++;
        }
 
        return;
    }
 
    // Iterating over the array arr
    for (let i = index; i < arr.length; i++) {
 
        // Swapping current index with I
        let temp = arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
 
        // Calling recursion for current
        // condition
        getPermutations(arr, index + 1, k);
 
        // Resetting the swapped position.
        temp = arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
    }
}
 
function numberOfPermutations(n,k)
{
 
    // Initializing the variables
    //'mod' and 'ans'.
    let mod = 1e9 + 7;
 
    // Initializing the array 'arr'.
    let arr = [];
 
    // Pushing numbers in the array.
    for (let i = 0; i < n; i++) {
        arr.push(i);
    }
 
    // Calling recursive function 'getPermutations'
    getPermutations(arr, 0, k);
 
    // Returning 'ans'.
    return ans % mod;
}
 
// Driver Code
let N = 4;
let K = 2;
document.write(numberOfPermutations(N, K));
 
// This code is contributed by shinjanpatra
 
</script>


Output

7

Time Complexity: O(N * N!)

  • For recursively finding all permutations, there will be N! recursive calls,
  • And for each call, there will be a running loop with N iterations.
  • Hence, the overall time complexity will be O(N * N!).

Auxiliary Space: O(N)

Efficient Approach: The idea to solve the problem efficiently is by Counting Derangements of the array.

Follow the steps to solve the problem:

  • First fix the positions in the array such that arr[i] != i, Say there are ‘M‘ such positions. (0 <= M <= N – K)
  • Count the number of permutations with fixed M for that, and simply choose the indices having the arr[i] !=i
  • Find this using the simple combination formula NCM.
  • Then, construct a permutation for chosen indices such that for every chosen index, arr[i] !=i, this is nothing but the derangements, and find this using an exhaustive search.
  • Then do the casework to find the derangements according to the K value.

Below is the implementation of the above approach :

C++




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// Driver function to get the
// modular addition.
int add(long long a, long long b)
{
    int mod = 1e9 + 7;
    return ((a % mod) + (b % mod)) % mod;
}
 
// Driver function to get the
// modular multiplication.
int mul(long long a, long long b)
{
    int mod = 1e9 + 7;
    return ((a % mod) * 1LL * (b % mod)) % mod;
}
 
// Driver function to get the
// modular binary exponentiation.
int bin_pow(long long a, long long b)
{
    int mod = 1e9 + 7;
    a %= mod;
    long long res = 1;
    while (b > 0) {
        if (b & 1) {
            res = res * 1LL * a % mod;
        }
        a = a * 1LL * a % mod;
        b >>= 1;
    }
    return res;
}
 
// Driver function to get the
// modular division.
int reverse(long long x)
{
    int mod = 1e9 + 7;
    return bin_pow(x, mod - 2);
}
 
int numberOfPermutations(long long n, long long k)
{
 
    // Updating 'k' with 'n - k'.
    k = n - k;
 
    // Initializing the 'ans' by 1.
    int ans = 1;
 
    // Condition when 'k' is 1.
    if (k == 0 or k == 1) {
        return ans;
    }
 
    // Adding derangement for 'k' = 2.
    ans += mul(mul(n, n - 1), reverse(2));
 
    // Condition when 'k' is 2.
    if (k == 2) {
        return ans;
    }
 
    // Adding derangement for 'k' = 3.
    ans += mul(mul(n, mul(n - 1, n - 2)),
               reverse(3));
 
    // Condition when 'k' is 3.
    if (k == 3) {
        return ans;
    }
 
    // Adding derangement for 'k' = 4.
    int u = mul(n, mul(n - 1, mul(n - 2,
                                  n - 3)));
    ans = add(ans, mul(u, reverse(8)));
    ans = add(ans, mul(u, reverse(4)));
 
    return ans;
}
 
// Driver Code
int main()
{
    long long N = 4;
    long long K = 2;
 
    cout << numberOfPermutations(N, K);
    return 0;
}


Java




// Java program for the above approach
import java.util.ArrayList;
 
class GFG {
 
  // Driver function to get the
  // modular addition.
  static long add(long a, long b)
  {
    long mod = (int)1e9 + 7;
    return ((a % mod) + (b % mod)) % mod;
  }
 
  // Driver function to get the
  // modular multiplication.
  static long mul(long a, long b)
  {
    long mod = (int)1e9 + 7;
    return ((a % mod) * 1 * (b % mod)) % mod;
  }
 
  // Driver function to get the
  // modular binary exponentiation.
  static long bin_pow(long a, long b)
  {
    long mod = (int)1e9 + 7;
    a %= mod;
    long res = 1;
    while (b > 0) {
      if ((b & 1) != 0) {
        res = res * 1 * a % mod;
      }
      a = a * 1 * a % mod;
      b >>= 1;
    }
    return res;
  }
 
  // Driver function to get the
  // modular division.
  static long reverse(long x)
  {
    long mod = (int)1e9 + 7;
    return bin_pow(x, mod - 2);
  }
 
  static long numberOfPermutations(long n, long k)
  {
 
    // Updating 'k' with 'n - k'.
    k = n - k;
 
    // Initializing the 'ans' by 1.
    long ans = 1;
 
    // Condition when 'k' is 1.
    if (k == 0 || k == 1) {
      return ans;
    }
 
    // Adding derangement for 'k' = 2.
    ans += mul(mul(n, n - 1), reverse(2));
 
    // Condition when 'k' is 2.
    if (k == 2) {
      return ans;
    }
 
    // Adding derangement for 'k' = 3.
    ans += mul(mul(n, mul(n - 1, n - 2)),
               reverse(3));
 
    // Condition when 'k' is 3.
    if (k == 3) {
      return ans;
    }
 
    // Adding derangement for 'k' = 4.
    long u = mul(n, mul(n - 1, mul(n - 2,
                                   n - 3)));
    ans = add(ans, mul(u, reverse(8)));
    ans = add(ans, mul(u, reverse(4)));
 
    return ans;
  }
 
  // Driver Code
  public static void main(String args[]) {
    long N = 4;
    long K = 2;
 
    System.out.print( numberOfPermutations(N, K));
  }
}
 
// This code is contributed by sanjoy_62.


Python3




# Python3 code for the above approach:
 
# Driver function to get the
# modular addition.
def add(a, b):
    mod = int(1e9 + 7)
    return ((a % mod) + (b % mod)) % mod
 
# Driver function to get the
# modular multiplication.
def mul(a, b):
 
    mod = int(1e9 + 7)
    return ((a % mod) * (b % mod)) % mod
 
# Driver function to get the
# modular binary exponentiation.
def bin_pow(a, b):
 
    mod = int(1e9 + 7)
    a %= mod
    res = 1
    while (b > 0):
        if (b & 1):
            res = res * a % mod
 
        a = a * a % mod
        b >>= 1
 
    return res
 
# Driver function to get the
# modular division.
def reverse(x):
 
    mod = int(1e9 + 7)
    return bin_pow(x, mod - 2)
 
def numberOfPermutations(n, k):
 
    # Updating 'k' with 'n - k'.
    k = n - k
 
    # Initializing the 'ans' by 1.
    ans = 1
 
    # Condition when 'k' is 1.
    if (k == 0 or k == 1):
        return ans
 
    # Adding derangement for 'k' = 2.
    ans += mul(mul(n, n - 1), reverse(2))
 
    # Condition when 'k' is 2.
    if (k == 2):
        return ans
 
    # Adding derangement for 'k' = 3.
    ans += mul(mul(n, mul(n - 1, n - 2)),
               reverse(3))
 
    # Condition when 'k' is 3.
    if (k == 3):
        return ans
 
    # Adding derangement for 'k' = 4.
    u = mul(n, mul(n - 1, mul(n - 2,
                              n - 3)))
    ans = add(ans, mul(u, reverse(8)))
    ans = add(ans, mul(u, reverse(4)))
 
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    N = 4
    K = 2
 
    print(numberOfPermutations(N, K))
 
    # This code is contributed by rakeshsahni


C#




using System;
public class GFG {
 
  // Driver function to get the
  // modular addition.
  static long add(long a, long b)
  {
    long mod = (int)1e9 + 7;
    return ((a % mod) + (b % mod)) % mod;
  }
 
  // Driver function to get the
  // modular multiplication.
  static long mul(long a, long b)
  {
    long mod = (int)1e9 + 7;
    return ((a % mod) * 1 * (b % mod)) % mod;
  }
  // Driver function to get the
  // modular binary exponentiation.
  static long bin_pow(long a, long b)
  {
    long mod = (int)1e9 + 7;
    a %= mod;
    long res = 1;
    while (b > 0) {
      if ((b & 1) != 0) {
        res = res * 1 * a % mod;
      }
      a = a * 1 * a % mod;
      b >>= 1;
    }
    return res;
  }
  // Driver function to get the
  // modular division.
  static long reverse(long x)
  {
    long mod = (int)1e9 + 7;
    return bin_pow(x, mod - 2);
  }
  static long numberOfPermutations(long n, long k)
  {
 
    // Updating 'k' with 'n - k'.
    k = n - k;
 
    // Initializing the 'ans' by 1.
    long ans = 1;
 
    // Condition when 'k' is 1.
    if (k == 0 || k == 1) {
      return ans;
    }
 
    // Adding derangement for 'k' = 2.
    ans += mul(mul(n, n - 1), reverse(2));
 
    // Condition when 'k' is 2.
    if (k == 2) {
      return ans;
    }
 
    // Adding derangement for 'k' = 3.
    ans += mul(mul(n, mul(n - 1, n - 2)), reverse(3));
 
    // Condition when 'k' is 3.
    if (k == 3) {
      return ans;
    }
 
    // Adding derangement for 'k' = 4.
    long u = mul(n, mul(n - 1, mul(n - 2, n - 3)));
    ans = add(ans, mul(u, reverse(8)));
    ans = add(ans, mul(u, reverse(4)));
 
    return ans;
  }
 
  static public void Main()
  {
    long N = 4;
    long K = 2;
 
    Console.Write(numberOfPermutations(N, K));
  }
}
 
// This code is contributed by ukasp.


Javascript




// Driver function to get the
// modular addition.
function add(a, b) {
  let mod = BigInt(1e9 + 7);
  return (a % mod + b % mod) % mod;
}
// Driver function to get the
// modular multiplication.
function mul(a, b) {
  let mod = BigInt(1e9 + 7);
  return ((a % mod) * (b % mod)) % mod;
}
// Driver function to get the
// modular binary exponentiation.
function bin_pow(a, b) {
  let mod = BigInt(1e9 + 7);
  a %= mod;
  let res = BigInt(1);
  while (b > BigInt(0)) {
    if (b & BigInt(1)) {
      res = mul(res, a);
    }
    a = mul(a, a);
    b >>= BigInt(1);
  }
  return res;
}
 
// Driver function to get the
// modular division.
function reverse(x) {
  let mod = BigInt(1e9 + 7);
  return bin_pow(x, mod - BigInt(2));
}
function numberOfPermutations(n, k) {
  let mod = BigInt(1e9 + 7);
   // Updating 'k' with 'n - k'.
  k = BigInt(n - k);
 
   
 
    // Initializing the 'ans' by 1.
  let ans = BigInt(1);
    // Condition when 'k' is 1.
  if (k === BigInt(0) || k === BigInt(1)) {
    return ans;
  }
 // Adding derangement for 'k' = 2.
  ans += mul(mul(BigInt(n), BigInt(n - 1)), reverse(BigInt(2)));
 
 
 
    // Condition when 'k' is 2.
  if (k === BigInt(2)) {
    return ans;
  }
   // Adding derangement for 'k' = 3.
  ans += mul(mul(BigInt(n), mul(BigInt(n - 1), BigInt(n - 2))), reverse(BigInt(3)));
 
    // Condition when 'k' is 3.
  if (k === BigInt(3)) {
    return ans;
  }
// Adding derangement for 'k' = 4.
  let u = mul(BigInt(n), mul(BigInt(n - 1), mul(BigInt(n - 2), BigInt(n - 3))));
  ans = add(ans, mul(u, reverse(BigInt(8))));
  ans = add(ans, mul(u, reverse(BigInt(4))));
 
  return ans % mod;
}
 
 
// Driver Code
let N = 4;
let K = 2;
 
document.write(numberOfPermutations(N, K));


Output

7

Time Complexity: O(Log N)

  • For, using the binary exponential to get the inverse modulo of a number
  • the overall time complexity will be O( Log N )

Auxiliary Space: O(1)



Last Updated : 23 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads