Open In App

Count of possible unique arrays after swapping elements at same index of given Arrays

Last Updated : 06 Jun, 2024
Comments
Improve
Suggest changes
2 Likes
Like
Report

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:

  1. Create an unordered map to store elements of both arrays in key-value pairs
  2. Take a variable say count for the count of possible combinations and also take a vector for track of elements say visited.
  3. 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.
  4. 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.
  5. 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 Python C# JavaScript

Output
8

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

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)


Next Article
Article Tags :
Practice Tags :

Similar Reads