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
Output: 7
{1, 2, 3, 4}, {1, 2, 4, 3}, {4, 2, 3, 1}, {2, 1, 3, 4}, {1, 4, 3, 2}, {1, 3, 2, 4} and {3, 2, 1, 4} are the only possible special permutations.Input: n = 5, k = 3
Output: 31
Approach: Let the function fx denote the number of special permutations in which there exists exactly x indices such that Pi = i. Hence, the required answer will be:
f(n – k) + f(n – k + 1) + f(n – k + 2) + … + f(n – 1) + fn
Now, fx can be calculated by choosing x indices from n where Pi = i and calculating the number of derangements for (n – i) other indices as for them Pi should not be equal to i then multiplying the result by nCx as there can be different ways to select x indices from n.
Steps to solve the problem:
- Define a function nCr to calculate the number of combinations of n items taken r at a time using the formula n! / (r! * (n-r)!)
- Define a function countDerangements to calculate the number of derangements of n items using the formula der(n) = (n-1) * (der(n-1) + der(n-2)) where der(0) = 1 and der(1) = 0.
- Define a function countPermutations to calculate the number of permutations of n items where no more than k items are in their original positions using the following steps.
- Initialize a variable ans to 0.
- Loop through i from n-k to n.
- Calculate the number of ways to choose i items from n items using the nCr function.
- Calculate the number of derangements of n-i items using the countDerangements function.
- Multiply the number of ways and the number of derangements and add the result to and.
- Return ans as the result of the function.
Below is the implementation of the above approach:
C++
// C++ program to count the number// of required permutations#include <bits/stdc++.h>using namespace std;#define ll long long int// Function to return the number of ways// to choose r objects out of n objectsint nCr(int n, int r){ int ans = 1; if (r > n - r) r = n - r; for (int i = 0; i < r; i++) { ans *= (n - i); ans /= (i + 1); } return ans;}// Function to return the number// of derangements of nint countDerangements(int n){ int der[n + 1]; der[0] = 1; der[1] = 0; der[2] = 1; for (int i = 3; i <= n; i++) der[i] = (i - 1) * (der[i - 1] + der[i - 2]); return der[n];}// Function to return the required// number of permutationsll countPermutations(int n, int k){ ll ans = 0; for (int i = n - k; i <= n; i++) { // Ways to choose i indices from n indices int ways = nCr(n, i); // Derangements of (n - i) indices ans += ways * countDerangements(n - i); } return ans;}// Driver Code to test above functionsint main(){ int n = 5, k = 3; cout << countPermutations(n, k); return 0;} |
Java
// Java program to count the number // of required permutations public class GFG{ // Function to return the number of ways // to choose r objects out of n objects static int nCr(int n, int r) { int ans = 1; if (r > n - r) r = n - r; for (int i = 0; i < r; i++) { ans *= (n - i); ans /= (i + 1); } return ans; } // Function to return the number // of derangements of n static int countDerangements(int n) { int der[] = new int[ n + 3]; der[0] = 1; der[1] = 0; der[2] = 1; for (int i = 3; i <= n; i++) der[i] = (i - 1) * (der[i - 1] + der[i - 2]); return der[n]; } // Function to return the required // number of permutations static int countPermutations(int n, int k) { int ans = 0; for (int i = n - k; i <= n; i++) { // Ways to choose i indices from n indices int ways = nCr(n, i); // Derangements of (n - i) indices //System.out.println(ans) ; ans += (ways * countDerangements(n- i)); } return ans; } // Driver Code to test above functions public static void main(String []args) { int n = 5, k = 3; System.out.println(countPermutations(n, k)) ; } // This code is contributed by Ryuga} |
Python3
# Python 3 program to count the number# of required permutation# function to return the number of ways # to chooser objects out of n objectsdef nCr(n, r): ans = 1 if r > n - r: r = n - r for i in range(r): ans *= (n - i) ans /= (i + 1) return ans# function to return the number of# degrangemnets of ndef countDerangements(n): der = [0 for i in range(n + 3)] der[0] = 1 der[1] = 0 der[2] = 1 for i in range(3, n + 1): der[i] = (i - 1) * (der[i - 1] + der[i - 2]) return der[n]# function to return the required # number of permutationsdef countPermutations(n, k): ans = 0 for i in range(n - k, n + 1): # ways to choose i indices # from n indices ways = nCr(n, i) # Derangements of (n-i) indices ans += ways * countDerangements(n - i) return ans# Driver Coden, k = 5, 3print(countPermutations(n, k))# This code is contributed by# Mohit kumar 29 (IIIT gwalior) |
C#
// C# program to count the number // of required permutationsusing System; public class GFG{ // Function to return the number of ways // to choose r objects out of n objects static int nCr(int n, int r) { int ans = 1; if (r > n - r) r = n - r; for (int i = 0; i < r; i++) { ans *= (n - i); ans /= (i + 1); } return ans; } // Function to return the number // of derangements of n static int countDerangements(int n) { int []der = new int[ n + 3]; der[0] = 1; der[1] = 0; der[2] = 1; for (int i = 3; i <= n; i++) der[i] = (i - 1) * (der[i - 1] + der[i - 2]); return der[n]; } // Function to return the required // number of permutations static int countPermutations(int n, int k) { int ans = 0; for (int i = n - k; i <= n; i++) { // Ways to choose i indices from n indices int ways = nCr(n, i); // Derangements of (n - i) indices //System.out.println(ans) ; ans += (ways * countDerangements(n- i)); } return ans; } // Driver Code to test above functions public static void Main() { int n = 5, k = 3; Console.WriteLine(countPermutations(n, k)) ; } }// This code is contributed by 29AjayKumar |
Javascript
<script> // JavaScript program to count the number // of required permutations // Function to return the number of ways // to choose r objects out of n objects function nCr(n, r) { var ans = 1; if (r > n - r) r = n - r; for (var i = 0; i < r; i++) { ans *= n - i; ans /= i + 1; } return ans; } // Function to return the number // of derangements of n function countDerangements(n) { var der = [...Array(n + 1)]; der[0] = 1; der[1] = 0; der[2] = 1; for (var i = 3; i <= n; i++) der[i] = (i - 1) * (der[i - 1] + der[i - 2]); return der[n]; } // Function to return the required // number of permutations function countPermutations(n, k) { var ans = 0; for (var i = n - k; i <= n; i++) { // Ways to choose i indices from n indices var ways = nCr(n, i); // Derangements of (n - i) indices ans += ways * countDerangements(n - i); } return ans; } // Driver Code to test above functions var n = 5, k = 3; document.write(countPermutations(n, k)); </script> |
PHP
<?php// PHP program to count the number// of required permutations// Function to return the number of ways// to choose r objects out of n objectsfunction nCr($n, $r){ $ans = 1; if ($r > $n - $r) $r = $n - $r; for ($i = 0; $i < $r; $i++) { $ans *= ($n - $i); $ans /= ($i + 1); } return $ans;}// Function to return the number// of derangements of nfunction countDerangements($n){ $der = array($n + 1); $der[0] = 1; $der[1] = 0; $der[2] = 1; for ($i = 3; $i <= $n; $i++) $der[$i] = ($i - 1) * ($der[$i - 1] + $der[$i - 2]); return $der[$n];}// Function to return the required// number of permutationsfunction countPermutations($n, $k){ $ans = 0; for ($i = $n - $k; $i <= $n; $i++) { // Ways to choose i indices // from n indices $ways = nCr($n, $i); // Derangements of (n - i) indices $ans += $ways * countDerangements($n - $i); } return $ans;}// Driver Code$n = 5;$k = 3;echo (countPermutations($n, $k));// This code is contributed // by Shivi_Aggarwal ?> |
31
Time Complexity: O(N^2), since there runs a loop inside another loop.
Auxiliary Space: O(N), since N extra space has been taken.
Efficient approach : Space optimization O(1)
In previous approach we the current value dp[i] is only depend upon the previous 2 values i.e. dp[i-1] and dp[i-2]. So to optimize the space we can keep track of previous and current values by the help of three variables prev1, prev2 and curr which will reduce the space complexity from O(N) to O(1).
Implementation Steps:
- Create 2 variables prev1 and prev2 to keep track o previous values of DP.
- Initialize base case prev1 = 0 and prev2 = 1.
- Create a variable curr to store current value.
- Iterate over subproblem using loop and update curr.
- After every iteration update prev1 and prev2 for further iterations.
- At last return curr.
Implementation:
C++
// C++ program to count the number// of required permutations#include <bits/stdc++.h>using namespace std;#define ll long long int// Function to return the number of ways// to choose r objects out of n objectsint nCr(int n, int r){ int ans = 1; if (r > n - r) r = n - r; for (int i = 0; i < r; i++) { ans *= (n - i); ans /= (i + 1); } return ans;}// Function to return the number// of derangements of nint countDerangements(int n){ // to store previous values of DP int prev0=1 , prev1=0 , prev2=1; // to store current value int curr; // Base Case if(n == 0) return prev0; if(n == 1) return prev1; if(n == 2) return prev2; // iterate over subproblems to gee the current // value from previous computations for (int i = 3; i <= n; i++){ curr = (i-1) * ( prev2 + prev1 ) ; // assigning values for further iterations prev1 = prev2; prev2 = curr; } // return answer return curr;}// Function to return the required// number of permutationsll countPermutations(int n, int k){ ll ans = 0; for (int i = n - k; i <= n; i++) { // Ways to choose i indices from n indices int ways = nCr(n, i); // Derangements of (n - i) indices ans += ways * countDerangements(n - i); } return ans;}// Driver Code to test above functionsint main(){ int n = 5, k = 3; cout << countPermutations(n, k); return 0;} |
Java
import java.util.*;public class Main { // Function to return the number of ways // to choose r objects out of n objects public static int nCr(int n, int r) { int ans = 1; if (r > n - r) r = n - r; for (int i = 0; i < r; i++) { ans *= (n - i); ans /= (i + 1); } return ans; } // Function to return the number // of derangements of n public static int countDerangements(int n) { // to store previous values of DP int prev0=1 , prev1=0 , prev2=1; // to store current value int curr; // Base Case if(n == 0) return prev0; if(n == 1) return prev1; if(n == 2) return prev2; // iterate over subproblems to gee the current // value from previous computations for (int i = 3; i <= n; i++){ curr = (i-1) * ( prev2 + prev1 ) ; // assigning values for further iterations prev1 = prev2; prev2 = curr; } // return answer return prev2; } // Function to return the required // number of permutations public static long countPermutations(int n, int k) { long ans = 0; for (int i = n - k; i <= n; i++) { // Ways to choose i indices from n indices int ways = nCr(n, i); // Derangements of (n - i) indices ans += ways * countDerangements(n - i); } return ans; } // Driver Code to test above functions public static void main(String[] args) { int n = 5, k = 3; System.out.println(countPermutations(n, k)); }} |
Python
# Python program to count the number# of required permutationsimport math# Function to return the number of ways# to choose r objects out of n objectsdef nCr(n, r): ans = 1 if (r > n - r): r = n - r for i in range(r): ans *= (n - i) ans //= (i + 1) return ans# Function to return the number# of derangements of ndef countDerangements(n): # to store previous values of DP prev0, prev1, prev2 = 1, 0, 1 # Base Case if n == 0: return prev0 if n == 1: return prev1 if n == 2: return prev2 # iterate over subproblems to get the current # value from previous computations for i in range(3, n + 1): curr = (i - 1) * (prev2 + prev1) # assigning values for further iterations prev1 = prev2 prev2 = curr # return answer return curr# Function to return the required# number of permutationsdef countPermutations(n, k): ans = 0 for i in range(n - k, n + 1): # Ways to choose i indices from n indices ways = nCr(n, i) # Derangements of (n - i) indices ans += ways * countDerangements(n - i) return ans# Driver Code to test above functionsif __name__ == '__main__': n = 5 k = 3 print(countPermutations(n, k)) |
C#
using System;public class Program{ // Function to return the number of ways // to choose r objects out of n objects static int nCr(int n, int r) { int ans = 1; if (r > n - r) r = n - r; for (int i = 0; i < r; i++) { ans *= (n - i); ans /= (i + 1); } return ans; } // Function to return the number // of derangements of n static int CountDerangements(int n) { // to store previous values of DP int prev0 = 1, prev1 = 0, prev2 = 1; // to store current value int curr = 0; // Initialize curr // Base Case if (n == 0) return prev0; if (n == 1) return prev1; if (n == 2) return prev2; // iterate over subproblems to get the current // value from previous computations for (int i = 3; i <= n; i++) { curr = (i - 1) * (prev2 + prev1); // assigning values for further iterations prev1 = prev2; prev2 = curr; } // return answer return curr; } // Function to return the required // number of permutations static long CountPermutations(int n, int k) { long ans = 0; for (int i = n - k; i <= n; i++) { // Ways to choose i indices from n indices int ways = nCr(n, i); // Derangements of (n - i) indices ans += ways * CountDerangements(n - i); } return ans; } // Driver Code public static void Main() { int n = 5, k = 3; Console.WriteLine(CountPermutations(n, k)); }} |
Javascript
// Function to return the number of ways// to choose r objects out of n objectsfunction nCr(n, r) { let ans = 1; if (r > n - r) r = n - r; for (let i = 0; i < r; i++) { ans *= (n - i); ans /= (i + 1); } return ans;}// Function to return the number// of derangements of nfunction countDerangements(n) { // to store previous values of DP let prev0 = 1, prev1 = 0, prev2 = 1; // to store current value let curr; // Base Case if (n === 0) return prev0; if (n === 1) return prev1; if (n === 2) return prev2; // iterate over subproblems to get the current // value from previous computations for (let i = 3; i <= n; i++) { curr = (i - 1) * (prev2 + prev1); // assigning values for further iterations prev1 = prev2; prev2 = curr; } // return answer return curr;}// Function to return the required// number of permutationsfunction countPermutations(n, k) { let ans = 0; for (let i = n - k; i <= n; i++) { // Ways to choose i indices from n indices let ways = nCr(n, i); // Derangements of (n - i) indices ans += ways * countDerangements(n - i); } return ans;}// Driver Code to test above functionslet n = 5, k = 3;console.log(countPermutations(n, k)); |
31
Time Complexity: O(N^2), since there runs a loop inside another loop.
Auxiliary Space: O(1), since no extra space is used.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



