Count permutations of 0 to N-1 with at least K elements same as positions
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:
- [0, 1, 2, 3]
- [0, 1, 3, 2]
- [0, 3, 2, 1]
- [0, 2, 1, 3]
- [3, 1, 2, 0]
- [2, 1, 0, 3]
- [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++
#include <bits/stdc++.h>
using namespace std;
void getPermutations(vector< int >& arr,
int index, int k,
int & ans)
{
if (index >= arr.size()) {
int count = 0;
for ( int i = 0; i < arr.size(); i++) {
if (arr[i] == i) {
count++;
}
}
if (count >= k) {
ans++;
}
return ;
}
for ( int i = index; i < arr.size(); i++) {
swap(arr[index], arr[i]);
getPermutations(arr, index + 1, k, ans);
swap(arr[index], arr[i]);
}
}
int numberOfPermutations( long long n,
long long k)
{
int mod = 1e9 + 7;
int ans = 0;
vector< int > arr;
for ( int i = 0; i < n; i++) {
arr.push_back(i);
}
getPermutations(arr, 0, k, ans);
return ans % mod;
}
int main()
{
long long N = 4;
long long K = 2;
cout << numberOfPermutations(N, K);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int ans = 0 ;
static void getPermutations(Vector<Integer> arr,
int index, long k)
{
if (index >= arr.size()) {
int count = 0 ;
for ( int i = 0 ; i < arr.size(); i++) {
if (arr.get(i) == i) {
count++;
}
}
if (count >= k) {
ans++;
}
return ;
}
for ( int i = index; i < arr.size(); i++) {
int temp = arr.get(index);
arr.set(index, arr.get(i));
arr.set(i, temp);
getPermutations(arr, index + 1 , k);
temp = arr.get(index);
arr.set(index, arr.get(i));
arr.set(i, temp);
}
}
static int numberOfPermutations( long n,
long k)
{
int mod = 1000000000 + 7 ;
Vector<Integer> arr = new Vector<Integer>();
for ( int i = 0 ; i < n; i++) {
arr.add(i);
}
getPermutations(arr, 0 , k);
return ans % mod;
}
public static void main (String[] args) {
long N = 4 ;
long K = 2 ;
System.out.println(numberOfPermutations(N, K));
}
}
|
Python3
ans = 0
def getPermutations(arr, index, k):
global ans
if (index > = len (arr)):
count = 0
for i in range ( len (arr)):
if (arr[i] = = i):
count + = 1
if (count > = k):
ans + = 1
return
for i in range (index, len (arr)):
temp = arr[index]
arr[index] = arr[i]
arr[i] = temp
getPermutations(arr, index + 1 , k)
temp = arr[index]
arr[index] = arr[i]
arr[i] = temp
def numberOfPermutations(n, k):
mod = 1e9 + 7
arr = []
for i in range (n):
arr.append(i)
getPermutations(arr, 0 , k)
return int (ans % mod)
N = 4
K = 2
print (numberOfPermutations(N, K))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int ans = 0;
static void getPermutations(List< int > arr,
int index, long k)
{
if (index >= arr.Count) {
int count = 0;
for ( int i = 0; i < arr.Count; i++) {
if (arr[i] == i) {
count++;
}
}
if (count >= k) {
ans++;
}
return ;
}
for ( int i = index; i < arr.Count; i++) {
int temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
getPermutations(arr, index + 1, k);
temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
}
}
static int numberOfPermutations( long n,
long k)
{
int mod = 1000000000 + 7;
List< int > arr = new List< int >();
for ( int i = 0; i < n; i++) {
arr.Add(i);
}
getPermutations(arr, 0, k);
return ans % mod;
}
public static void Main()
{
long N = 4;
long K = 2;
Console.Write(numberOfPermutations(N, K));
}
}
|
Javascript
<script>
let ans = 0;
function getPermutations(arr, index, k)
{
if (index >= arr.length) {
let count = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] == i) {
count++;
}
}
if (count >= k) {
ans++;
}
return ;
}
for (let i = index; i < arr.length; i++) {
let temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
getPermutations(arr, index + 1, k);
temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
}
}
function numberOfPermutations(n,k)
{
let mod = 1e9 + 7;
let arr = [];
for (let i = 0; i < n; i++) {
arr.push(i);
}
getPermutations(arr, 0, k);
return ans % mod;
}
let N = 4;
let K = 2;
document.write(numberOfPermutations(N, K));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int add( long long a, long long b)
{
int mod = 1e9 + 7;
return ((a % mod) + (b % mod)) % mod;
}
int mul( long long a, long long b)
{
int mod = 1e9 + 7;
return ((a % mod) * 1LL * (b % mod)) % mod;
}
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;
}
int reverse( long long x)
{
int mod = 1e9 + 7;
return bin_pow(x, mod - 2);
}
int numberOfPermutations( long long n, long long k)
{
k = n - k;
int ans = 1;
if (k == 0 or k == 1) {
return ans;
}
ans += mul(mul(n, n - 1), reverse(2));
if (k == 2) {
return ans;
}
ans += mul(mul(n, mul(n - 1, n - 2)),
reverse(3));
if (k == 3) {
return ans;
}
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;
}
int main()
{
long long N = 4;
long long K = 2;
cout << numberOfPermutations(N, K);
return 0;
}
|
Java
import java.util.ArrayList;
class GFG {
static long add( long a, long b)
{
long mod = ( int )1e9 + 7 ;
return ((a % mod) + (b % mod)) % mod;
}
static long mul( long a, long b)
{
long mod = ( int )1e9 + 7 ;
return ((a % mod) * 1 * (b % mod)) % mod;
}
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;
}
static long reverse( long x)
{
long mod = ( int )1e9 + 7 ;
return bin_pow(x, mod - 2 );
}
static long numberOfPermutations( long n, long k)
{
k = n - k;
long ans = 1 ;
if (k == 0 || k == 1 ) {
return ans;
}
ans += mul(mul(n, n - 1 ), reverse( 2 ));
if (k == 2 ) {
return ans;
}
ans += mul(mul(n, mul(n - 1 , n - 2 )),
reverse( 3 ));
if (k == 3 ) {
return ans;
}
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;
}
public static void main(String args[]) {
long N = 4 ;
long K = 2 ;
System.out.print( numberOfPermutations(N, K));
}
}
|
Python3
def add(a, b):
mod = int ( 1e9 + 7 )
return ((a % mod) + (b % mod)) % mod
def mul(a, b):
mod = int ( 1e9 + 7 )
return ((a % mod) * (b % mod)) % mod
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
def reverse(x):
mod = int ( 1e9 + 7 )
return bin_pow(x, mod - 2 )
def numberOfPermutations(n, k):
k = n - k
ans = 1
if (k = = 0 or k = = 1 ):
return ans
ans + = mul(mul(n, n - 1 ), reverse( 2 ))
if (k = = 2 ):
return ans
ans + = mul(mul(n, mul(n - 1 , n - 2 )),
reverse( 3 ))
if (k = = 3 ):
return ans
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
if __name__ = = "__main__" :
N = 4
K = 2
print (numberOfPermutations(N, K))
|
C#
using System;
public class GFG {
static long add( long a, long b)
{
long mod = ( int )1e9 + 7;
return ((a % mod) + (b % mod)) % mod;
}
static long mul( long a, long b)
{
long mod = ( int )1e9 + 7;
return ((a % mod) * 1 * (b % mod)) % mod;
}
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;
}
static long reverse( long x)
{
long mod = ( int )1e9 + 7;
return bin_pow(x, mod - 2);
}
static long numberOfPermutations( long n, long k)
{
k = n - k;
long ans = 1;
if (k == 0 || k == 1) {
return ans;
}
ans += mul(mul(n, n - 1), reverse(2));
if (k == 2) {
return ans;
}
ans += mul(mul(n, mul(n - 1, n - 2)), reverse(3));
if (k == 3) {
return ans;
}
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));
}
}
|
Javascript
function add(a, b) {
let mod = BigInt(1e9 + 7);
return (a % mod + b % mod) % mod;
}
function mul(a, b) {
let mod = BigInt(1e9 + 7);
return ((a % mod) * (b % mod)) % mod;
}
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;
}
function reverse(x) {
let mod = BigInt(1e9 + 7);
return bin_pow(x, mod - BigInt(2));
}
function numberOfPermutations(n, k) {
let mod = BigInt(1e9 + 7);
k = BigInt(n - k);
let ans = BigInt(1);
if (k === BigInt(0) || k === BigInt(1)) {
return ans;
}
ans += mul(mul(BigInt(n), BigInt(n - 1)), reverse(BigInt(2)));
if (k === BigInt(2)) {
return ans;
}
ans += mul(mul(BigInt(n), mul(BigInt(n - 1), BigInt(n - 2))), reverse(BigInt(3)));
if (k === BigInt(3)) {
return ans;
}
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;
}
let N = 4;
let K = 2;
document.write(numberOfPermutations(N, K));
|
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
Share your thoughts in the comments
Please Login to comment...