Count of permutations of an Array having each element as a multiple or a factor of its index
Given an integer, N, the task is to count the number of ways to generate an array, arr[] of consisting of N integers such that for every index i(1-based indexing), arr[i] is either a factor or a multiple of i, or both. The arr[] must be the permutations of all the numbers from the range [1, N].
Examples:
Input: N=2
Output: 2
Explanation:
Two possible arrangements are {1, 2} and {2, 1}
Input: N=3
Output: 3
Explanation:
The 6 possible arrangements are {1, 2, 3}, {2, 1, 3}, {3, 2, 1}, {3, 1, 2}, {2, 3, 1} and {1, 3, 2}.
Among them, the valid arrangements are {1, 2, 3}, {2, 1, 3} and {3, 2, 1}.
Approach: The problem can be solved using Backtracking technique and the concept of print all permutations using recursion. Follow the steps below to find the recurrence relation:
- Traverse the range [1, N].
- For the current index pos, if i % pos == 0 and i % pos == 0, then insert i into the arrangement and use the concept of Backtracking to find valid permutations.
- Remove i.
- Repeat the above steps for all values in the range [1, N], and finally, print the count of valid permutations.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findPermutation(unordered_set< int >& arr,
int N)
{
int pos = arr.size() + 1;
if (pos > N)
return 1;
int res = 0;
for ( int i = 1; i <= N; i++) {
if (arr.find(i) == arr.end()) {
if (i % pos == 0 or pos % i == 0) {
arr.insert(i);
res += findPermutation(arr, N);
arr.erase(arr.find(i));
}
}
}
return res;
}
int main()
{
int N = 5;
unordered_set< int > arr;
cout << findPermutation(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int findPermutation(Set<Integer>arr,
int N)
{
int pos = arr.size() + 1 ;
if (pos > N)
return 1 ;
int res = 0 ;
for ( int i = 1 ; i <= N; i++)
{
if (! arr.contains(i))
{
if (i % pos == 0 || pos % i == 0 )
{
arr.add(i);
res += findPermutation(arr, N);
arr.remove(i);
}
}
}
return res;
}
public static void main(String []args)
{
int N = 5 ;
Set<Integer> arr = new HashSet<Integer>();
System.out.print(findPermutation(arr, N));
}
}
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int findPermutation(HashSet< int >arr,
int N)
{
int pos = arr.Count + 1;
if (pos > N)
return 1;
int res = 0;
for ( int i = 1; i <= N; i++)
{
if (! arr.Contains(i))
{
if (i % pos == 0 || pos % i == 0)
{
arr.Add(i);
res += findPermutation(arr, N);
arr.Remove(i);
}
}
}
return res;
}
public static void Main(String []args)
{
int N = 5;
HashSet< int > arr = new HashSet< int >();
Console.Write(findPermutation(arr, N));
}
}
|
Javascript
<script>
function findPermutation(arr, N)
{
var pos = arr.size + 1;
if (pos > N)
return 1;
var res = 0;
for ( var i = 1; i <= N; i++)
{
if (!arr.has(i))
{
if (i % pos == 0 || pos % i == 0)
{
arr.add(i);
res += findPermutation(arr, N);
arr. delete (i);
}
}
}
return res;
}
var N = 5;
var arr = new Set();
document.write(findPermutation(arr, N));
</script>
|
Python3
def findPermutation(arr, N):
pos = len (arr) + 1
if (pos > N):
return 1
res = 0
for i in range ( 1 , N + 1 ):
if (i not in arr):
if (i % pos = = 0 or pos % i = = 0 ):
arr.add(i)
res + = findPermutation(arr, N)
arr.remove(i)
return res
N = 5
arr = set ()
print (findPermutation(arr, N))
|
Time Complexity: O(N×N!)
Auxiliary Space: O(N)
Using Brute Force in python:
Approach:
The first approach is to generate all possible permutations of the array and check if each element is a multiple or a factor of its index. We can do this using a recursive function to generate permutations and then checking each permutation.
- Define a function is_valid(arr) that takes an array arr and checks if each element is a multiple or a factor of its index. It returns True if all elements satisfy this condition, otherwise False.
- Define a recursive function generate_permutations(arr, l, r, valid_permutations) that generates all possible permutations of the array arr from index l to index r. For each permutation, it checks if it is valid using the function is_valid(arr). If a valid permutation is found, it is added to the list valid_permutations.
- Define a function count_permutations(n) that creates an array arr of size n, initializes it with values 1 to n, and calls the function generate_permutations() with arr, 0, n-1, and an empty list valid_permutations. It then returns the length of valid_permutations.
Call the function count_permutations() with the input n and print the result.
Python3
def is_valid(arr):
for i in range ( len (arr)):
if arr[i] % (i + 1 ) ! = 0 and (i + 1 ) % arr[i] ! = 0 :
return False
return True
def generate_permutations(arr, l, r, valid_permutations):
if l = = r:
if is_valid(arr):
valid_permutations.append(arr[:])
else :
for i in range (l, r + 1 ):
arr[l], arr[i] = arr[i], arr[l]
generate_permutations(arr, l + 1 , r, valid_permutations)
arr[l], arr[i] = arr[i], arr[l]
def count_permutations(n):
arr = [i + 1 for i in range (n)]
valid_permutations = []
generate_permutations(arr, 0 , n - 1 , valid_permutations)
return len (valid_permutations)
print (count_permutations( 2 ))
print (count_permutations( 3 ))
|
Time Complexity: O(n!)
Space Complexity: O(n!)
Python Solution (Dynamic Programming):
Approach:
- Initialize a 2D array dp to store the count of permutations. Each cell dp[i][j] represents the count of permutations with i elements and j numbers selected.
- Initialize the base case dp[0][0] = 1.
- Fill the dp array using dynamic programming. Iterate over the range [1, N] for the number of elements and [0, N] for the selected numbers.
- For each element i, iterate over the range [1, min(i, j)] to represent selecting each number up to i or j, whichever is smaller.
- Increment dp[i][j] by dp[i – 1][j – k] for permutations including the current number i, where k represents the selected number.
- Increment dp[i][j] by dp[i – 1][j] for permutations excluding the current number i.
- Sum up the counts of all valid permutations stored in dp[N].
- Return the count of valid permutations.
Python3
def countPermutations(N):
dp = [[ 0 ] * (N + 1 ) for _ in range (N + 1 )]
dp[ 0 ][ 0 ] = 1
for i in range ( 1 , N + 1 ):
for j in range (N + 1 ):
for k in range ( 1 , i + 1 ):
if i % k = = 0 or k % i = = 0 :
dp[i][j] + = dp[i - 1 ][j - 1 ]
count = sum (dp[N][ 1 :])
return count
print (countPermutations( 2 ))
|
Time Complexity: O(n^3)
Space Complexity: O(n^2)
Last Updated :
11 Mar, 2024
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...