Count of possible unique arrays after swapping elements at same index of given Arrays
Last Updated :
06 Jun, 2024
Given two arrays arr1[] and arr2[] with distinct elements of size N.The task is to count the total number of possible combinations after swapping elements at the same index of both the arrays such that there are no duplicates in both the arrays after performing the operation.
Examples:
Input: arr1[] = {1, 2, 3, 4}, arr2[] = {2, 1, 4, 3}, N = 4
Output: 4
Explanation: Possible combinations of arrays are:
- {1, 2, 3, 4} and {2, 1, 4, 3}
- {2, 1, 3, 4} and {1, 2, 4, 3}
- {1, 2, 4, 3} and {2, 1, 3, 4}
- {2, 1, 4, 3} and {1, 2, 3, 4}
The bold ones are swapped elements. So, total number of combinations = 4.
Input: arr1[] = {3, 6, 5, 2, 1, 4, 7}, arr2[] = {1, 7, 2, 4, 3, 5, 6}, N = 7
Output: 8
Approach: The idea is to iterate the array for every element and make a swap, then find for swapping of the current element, how many extra swaps are needed to make the array free from duplicates. Count every different combination as a group(set) i.e for each group there are two possibilities either to make a swap or to not make a swap, so the answer will be the sum of 2 raised to the power of the number of groups. Follow the below steps to solve the problem:
- Create an unordered map to store elements of both arrays in key-value pairs
- Take a variable say count for the count of possible combinations and also take a vector for track of elements say visited.
- Iterate over the map and check if the element is not visited, each time create a set and run a loop till the current index is not equal to i. In each iteration, insert the element of the current index of the map in the set and also update the current index. Mark all the elements as visited in the set.
- After each iteration, while making groups(set), multiply the count by 2 as there are two possibilities for each group of swapping or not swapping of elements.
- In the end, return the count.
Below is the implementation of the above approach:
C++
// C++ implementation for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to count possible combinations
// of arrays after swapping of elements
// such that there are no duplicates
// in the arrays
int possibleCombinations(int arr1[], int arr2[], int N)
{
// Create an unordered_map
unordered_map<int, int> mp;
// Traverse both the arrays and
// store the elements of arr2[]
// in arr1[] element index in
// the map
for (int i = 0; i < N; i++) {
mp[arr1[i]] = arr2[i];
}
// Take a variable for count of
// possible combinations
int count = 1;
// Vector to keep track of already
// swapped elements
vector<bool> visited(N + 1, 0);
for (int i = 1; i <= N; i++) {
// If the element is not visited
if (!visited[i]) {
// Create a set
set<int> s;
// Variable to store the current index
int curr_index = i;
// Iterate a loop till curr_index
// is equal to i
do {
// Insert the element in the set
// of current index in map
s.insert(mp[curr_index]);
// Assign it to curr_index
curr_index = mp[curr_index];
} while (curr_index != i);
// Iterate over the set and
// mark element as visited
for (auto it : s) {
visited[it] = 1;
}
count *= 2;
}
}
return count;
}
// Driver Code
int main()
{
int arr1[] = { 3, 6, 5, 2, 1, 4, 7 };
int arr2[] = { 1, 7, 2, 4, 3, 5, 6 };
int N = sizeof(arr1) / sizeof(arr1[0]);
cout << possibleCombinations(arr1, arr2, N);
return 0;
}
Java
// Java implementation for the above approach
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
class GFG
{
// Function to count possible combinations
// of arrays after swapping of elements
// such that there are no duplicates
// in the arrays
public static int possibleCombinations(int arr1[], int arr2[], int N)
{
// Create an unordered_map
HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>();
// Traverse both the arrays and
// store the elements of arr2[]
// in arr1[] element index in
// the map
for (int i = 0; i < N; i++) {
mp.put(arr1[i], arr2[i]);
}
// Take a variable for count of
// possible combinations
int count = 1;
// Vector to keep track of already
// swapped elements
int[] visited = new int[N + 1];
Arrays.fill(visited, 0);
for (int i = 1; i <= N; i++) {
// If the element is not visited
if (visited[i] <= 0) {
// Create a set
HashSet<Integer> s = new HashSet<Integer>();
// Variable to store the current index
int curr_index = i;
// Iterate a loop till curr_index
// is equal to i
do {
// Insert the element in the set
// of current index in map
s.add(mp.get(curr_index));
// Assign it to curr_index
curr_index = mp.get(curr_index);
} while (curr_index != i);
// Iterate over the set and
// mark element as visited
for (int it : s) {
visited[it] = 1;
}
count *= 2;
}
}
return count;
}
// Driver Code
public static void main(String args[]) {
int arr1[] = { 3, 6, 5, 2, 1, 4, 7 };
int arr2[] = { 1, 7, 2, 4, 3, 5, 6 };
int N = arr1.length;
System.out.println(possibleCombinations(arr1, arr2, N));
}
}
// This code is contributed by gfgking.
Python
# Python3 implementation for the above approach
# Function to count possible combinations
# of arrays after swapping of elements
# such that there are no duplicates
# in the arrays
def possibleCombinations(arr1, arr2, N) :
# Create an unordered_map
mp = {};
# Traverse both the arrays and
# store the elements of arr2[]
# in arr1[] element index in
# the map
for i in range(N) :
mp[arr1[i]] = arr2[i];
# Take a variable for count of
# possible combinations
count = 1;
# Vector to keep track of already
# swapped elements
visited = [0]*(N + 1);
for i in range(1 , N + 1) :
# If the element is not visited
if (not visited[i]) :
# Create a set
s = set();
# Variable to store the current index
curr_index = i;
# Iterate a loop till curr_index
# is equal to i
while True :
# Insert the element in the set
# of current index in map
s.add(mp[curr_index]);
# Assign it to curr_index
curr_index = mp[curr_index];
if (curr_index == i) :
break
# Iterate over the set and
# mark element as visited
for it in s :
visited[it] = 1;
count *= 2;
return count;
# Driver Code
if __name__ == "__main__" :
arr1 = [ 3, 6, 5, 2, 1, 4, 7 ];
arr2 = [ 1, 7, 2, 4, 3, 5, 6 ];
N = len(arr1);
print(possibleCombinations(arr1, arr2, N));
# This code is contributed by AnkThon
C#
// C# implementation for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to count possible combinations
// of arrays after swapping of elements
// such that there are no duplicates
// in the arrays
public static int
possibleCombinations(int[] arr1, int[] arr2, int N)
{
// Create an unordered_map
Dictionary<int, int> mp
= new Dictionary<int, int>();
// Traverse both the arrays and
// store the elements of arr2[]
// in arr1[] element index in
// the map
for (int i = 0; i < N; i++) {
mp[arr1[i]] = arr2[i];
}
// Take a variable for count of
// possible combinations
int count = 1;
// Vector to keep track of already
// swapped elements
int[] visited = new int[N + 1];
for (int i = 1; i <= N; i++) {
// If the element is not visited
if (visited[i] <= 0) {
// Create a set
HashSet<int> s = new HashSet<int>();
// Variable to store the current index
int curr_index = i;
// Iterate a loop till curr_index
// is equal to i
do {
// Insert the element in the set
// of current index in map
s.Add(mp[curr_index]);
// Assign it to curr_index
curr_index = mp[curr_index];
} while (curr_index != i);
// Iterate over the set and
// mark element as visited
foreach(int it in s) { visited[it] = 1; }
count *= 2;
}
}
return count;
}
// Driver Code
public static void Main(string[] args)
{
int[] arr1 = { 3, 6, 5, 2, 1, 4, 7 };
int[] arr2 = { 1, 7, 2, 4, 3, 5, 6 };
int N = arr1.Length;
Console.WriteLine(
possibleCombinations(arr1, arr2, N));
}
}
// This code is contributed by ukasp.
JavaScript
<script>
// Javascript implementation for the above approach
// Function to count possible combinations
// of arrays after swapping of elements
// such that there are no duplicates
// in the arrays
function possibleCombinations(arr1, arr2, N)
{
// Create an unordered_map
var mp = new Map();
// Traverse both the arrays and
// store the elements of arr2[]
// in arr1[] element index in
// the map
for (var i = 0; i < N; i++) {
mp.set(arr1[i], arr2[i]);
}
// Take a variable for count of
// possible combinations
var count = 1;
// Vector to keep track of already
// swapped elements
var visited = Array(N + 1).fill(false);
for (var i = 1; i <= N; i++) {
// If the element is not visited
if (!visited[i]) {
// Create a set
var s = new Set();
// Variable to store the current index
var curr_index = i;
// Iterate a loop till curr_index
// is equal to i
do {
// Insert the element in the set
// of current index in map
s.add(mp.get(curr_index));
// Assign it to curr_index
curr_index = mp.get(curr_index);
} while (curr_index != i);
// Iterate over the set and
// mark element as visited
for (var it of [...s]) {
visited[it] = true;
}
count *= 2;
}
}
return count;
}
// Driver Code
var arr1 = [3, 6, 5, 2, 1, 4, 7];
var arr2 = [1, 7, 2, 4, 3, 5, 6];
var N = arr1.length;
document.write(possibleCombinations(arr1, arr2, N));
// This code is contributed by rutvik_56.
</script>
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Union-Find Approach to Count Unique Array Combinations After Swapping
This approach leverages the Union-Find (Disjoint Set Union) data structure to efficiently group elements and count the number of possible unique combinations after swapping elements at the same index in two arrays. This method significantly reduces the time complexity compared to the provided approach.
The Union-Find structure allows us to efficiently manage and find groups of elements that can be swapped without creating duplicates, making it much faster to compute the total number of valid combinations.
Approach:
- Initialize the Union-Find structure with parent and rank arrays.
- For each index, perform union operations to group elements that can be swapped.
- Count the unique groups using the parent array.
- Compute the total combinations based on the number of groups.
C++
#include <iostream>
#include <vector>
#include <unordered_set>
class UnionFind {
private:
std::vector<int> parent;
std::vector<int> rank;
public:
UnionFind(int size) : parent(size), rank(size, 1) {
for (int i = 0; i < size; ++i) {
parent[i] = i;
}
}
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]); // Path compression
}
return parent[x];
}
void unionSets(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
if (rank[rootX] > rank[rootY]) {
parent[rootY] = rootX;
} else if (rank[rootX] < rank[rootY]) {
parent[rootX] = rootY;
} else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
};
int possibleCombinations(std::vector<int>& arr1, std::vector<int>& arr2) {
int N = arr1.size();
UnionFind uf(N + 1);
// Union the indices based on the values in arr1 and arr2
for (int i = 0; i < N; ++i) {
uf.unionSets(arr1[i], arr2[i]);
}
// Count the number of unique groups
std::unordered_set<int> uniqueGroups;
for (int i = 1; i <= N; ++i) {
uniqueGroups.insert(uf.find(i));
}
// Each group can either be swapped or not, so 2^uniqueGroups.size()
return 1 << uniqueGroups.size();
}
int main() {
std::vector<int> arr1 = {3, 6, 5, 2, 1, 4, 7};
std::vector<int> arr2 = {1, 7, 2, 4, 3, 5, 6};
std::cout << possibleCombinations(arr1, arr2) << std::endl; // Output: 8
return 0;
}
// This code is contributed by Shivam Gupta
Python
# Class for Union-Find (Disjoint Set Union) data structure
class UnionFind:
def __init__(self, size):
self.parent = list(range(size))
self.rank = [1] * size
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # Path compression
return self.parent[x]
def union(self, x, y):
rootX = self.find(x)
rootY = self.find(y)
if rootX != rootY:
if self.rank[rootX] > self.rank[rootY]:
self.parent[rootY] = rootX
elif self.rank[rootX] < self.rank[rootY]:
self.parent[rootX] = rootY
else:
self.parent[rootY] = rootX
self.rank[rootX] += 1
# Function to count possible combinations of arrays after swapping
def possibleCombinations(arr1, arr2, N):
uf = UnionFind(N + 1)
# Union the indices based on the values in arr1 and arr2
for i in range(N):
uf.union(arr1[i], arr2[i])
# Count the number of unique groups
unique_groups = len(set(uf.find(i) for i in range(1, N + 1)))
# Each group can either be swapped or not, so 2^unique_groups
return 2 ** unique_groups
# Driver Code
if __name__ == "__main__":
arr1 = [3, 6, 5, 2, 1, 4, 7]
arr2 = [1, 7, 2, 4, 3, 5, 6]
N = len(arr1)
print(possibleCombinations(arr1, arr2, N)) # Output: 8
Time Complexity: O(N⋅α(N)), where α is the inverse Ackermann function, which is very small and almost constant for all practical purposes
Auxiliary Complexity: O(N)
Similar Reads
Count elements of same value placed at same indices of two given arrays
Given two arrays A[] and B[] of N unique elements, the task is to find the maximum number of matched elements from the two given arrays. Elements of the two arrays are matched if they are of the same value and can be placed at the same index (0-based indexing).(By right shift or left shift of the tw
8 min read
Check if an array can be converted to another given array by swapping pairs of unequal elements
Given two arrays arr1[] and arr2[] of size N, consisting of binary integers, the task is to check if arr1[] can be converted to arr2[] by swapping any pair of array elements (arr1[i], arr1[j]) such that i < j and arr1[i] is 1 and arr1[j] is 0 (any number of times). If it is possible to do so, the
11 min read
Check if an array can be sorted by swapping pairs from indices consisting of unequal elements in another array
Given an array A[] of size N and a binary array B[] of size N, the task is to check if the array A[] can be converted into a sorted array by swapping pairs (A[i], A[j]) if B[i] is not equal to B[j]. If the array A[] can be sorted, then print "Yes". Otherwise, print "No". Examples: Input: A[] = {3, 1
15 min read
Count of all possible Arrays such that each array element can be over the range [1, arr[i]]
Given an array arr[] consisting of N positive integers, the task is to find the number of all possible arrays such that each array element can be over the range [1, arr[i]] all elements in the newly constructed array must be pairwise distinct. Examples: Input: arr[] = {5}Output: 5Explanation:All pos
5 min read
Find a pair of elements swapping which makes sum of two arrays same
Given two arrays of integers, find a pair of values (one value from each array) that you can swap to give the two arrays the same sum.Examples: Input: A[] = {4, 1, 2, 1, 1, 2}, B[] = (3, 6, 3, 3) Output: 1 3 Explanation: Sum of elements in A[] = 11 and Sum of elements in B[] = 15. To get same sum fr
15+ min read
Count of index pairs with equal elements in an array | Set 2
Given an array arr[] of N elements. The task is to count the total number of indices (i, j) such that arr[i] = arr[j] and i != j Examples: Input: arr[]={1, 2, 1, 1}Output: 3 Explanation:In the array arr[0]=arr[2]=arr[3]Valid Pairs are (0, 2), (0, 3) and (2, 3) Input: arr[]={2, 2, 3, 2, 3}Output: 4Ex
8 min read
Construct Binary Array having same number of unequal elements with two other Arrays
Given two binary arrays A[] and B[] of size N, the task is to construct the lexicographically smallest binary array X[] such that the number of non-equal elements in A and X is equal to the number of non-equal elements in B and X. If such an array does not exist return -1. Note: If there are multipl
12 min read
Find Number of Unique Elements in an Array After each Query
Given 2d array A[][1] of size N and array Q[][2] of size M representing M queries of type {a, b}. The task for this problem is in each query move all elements from A[a] to A[b] and print the number of unique elements in A[b]. Constraints: 1 <= N, Q <= 1051 <= A[i] <= 1091 <= a, b <
10 min read
Count Array elements that occur before any of its prefix value of another Array
Given two arrays A[] and B[] of size N each, the task is to find the number of elements in array B[] that occur before any element that was present before it in array A[]. Example: Input: N = 5, A[] = {3, 5, 1, 2, 4}, B[] = {4, 3, 1, 5, 2}Output: 2Explanation: Array A represent that 3 comes first th
6 min read
Rearrange given array such that no array element is same as its index
Given an array arr[] consisting of N distinct integers, the task is to rearrange the array such that no element is same as its index ( 1-based indexing ). If multiple solutions exist, print any one of them. Examples: Input: arr[] = {4, 2, 3, 1}Output: 3 1 4 2Explanation: The elements at indices {1,
7 min read