Open In App

Convert many to many mappings to maximum no of one to one mappings

Last Updated : 16 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr1 containing integers from 1..N and another array arr2 containing integers from 1..M. Each element of arr1 is mapped to more than one element in arr2. The task is to maximize the number of one to one mappings possible between both arrays. Here one to one mappings means a unique element of arr1 must be mapped to unique element of arr2. Mapping is given in the form of vector of pairs V where V.first() denotes elements of arr1 and V.second() denotes elements of arr2. Examples:

Input:  N = 3, M = 3
        arr1[] = {1, 2, 3}
        arr2[] = {1, 2, 3}
        V = { {1, 1}, {2, 1}, {2, 2},
              {3, 1}, {3, 2}, {3, 3} }
Output: 3
Explanation: 
If we carefully see here mappings are 
              1 -------->  {1}
              2 -------->  {1, 2}
              3 -------->  {1, 2, 3}
so, maximum number of unique pairings
can be done as
              1 -------->  {1}
              2 -------->  {2}
              3 -------->  {3}

Input: N = 3, M = 1
        V = { {1, 1}, {2, 1}, {3, 1} };
Output: 1
Explanation: 
Either 1 can be mapped or 2 or 3.
so maximum one mapping is possible.

Approach: The approach used here is Greedy. Preprocessing step We are given a vector of pairs which contains mapping information in an unsorted way for eg- 

 so, we convert this mapping information into a vector of sets mapping. For eg

:  

This is representing the information in one to many mapping form. This can be easily understood by the below diagram

  Steps:

  1. Find the element in arr1[] which has least number of mappings with elements of arr2[].
  2. Map this element to first element of its corresponding set.
  3. Delete all the mappings of this element.
  4. Also delete all the mappings which contain element from arr2[] those are already mapped.
  5. Repeat these four steps for all the elements of arr1[].

Below is the implementation of Above approach: 

CPP




// C++ Program to convert many to many mapping
// to maximum no of one to one mappings
  
#include <bits/stdc++.h>
using namespace std;
  
// Returns the maximum number
// of one to one mappings between two arrays
int FindMax(vector<pair<int, int> >& V, int N, int M)
{
    int ans = 0;
  
    // Stores whether an element
    // from the first array is used in mapping
    bool* is_paired = new bool[N];
  
    // Contains mapping in sorted form
    vector<set<int> > mapping(N + 1);
  
    // Initialize all the elements
    // of first array unused
    memset(is_paired, sizeof(is_paired), false);
  
    // Insert mappings in sorted form
    for (int i = 0; i < V.size(); i++) {
        mapping[V[i].first].insert(V[i].second);
    }
  
    // While there is always at least one element
    // which can be mapped to a unique element
    while (true) {
        int lowest = -1;
  
        // Finds element to be mapped
        for (int i = 1; i <= N; i++) {
  
            // There is mapping possible
            if (mapping[i].size() > 0) {
                if (lowest == -1)
                    lowest = i;
                else if (mapping[i].size()
                         < mapping[lowest].size())
                    lowest = i;
            }
        }
  
        if (lowest == -1)
            break;
  
        // Element used in the mapping
        is_paired[lowest] = true;
  
        int remove = *mapping[lowest].begin();
  
        // Delete all the mappings of used element
        for (int i = 1; i <= N; i++) {
  
            mapping[i].erase(remove);
            if (i == lowest) {
                mapping[i].clear();
            }
        }
        ans++;
    }
    return ans;
}
  
// Main Function
int main()
{
    int N = 3;
    int M = 3;
    int arr1[] = { 1, 2, 3 };
    int arr2[] = { 1, 2, 3 };
  
    vector<pair<int, int> >
        V{ { 1, 1 }, { 2, 1 }, { 2, 2 }, { 3, 1 }, { 3, 2 }, { 3, 3 } };
  
    cout << FindMax(V, N, M) << endl;
  
    return 0;
}


Java




import java.util.*;
import java.util.stream.*;
 
// Tuple class definition
class Tuple<T1, T2> {
 
    // Data members
    public final T1 Item1;
    public final T2 Item2;
 
    // Constructor
    public Tuple(T1 item1, T2 item2)
    {
        this.Item1 = item1;
        this.Item2 = item2;
    }
}
 
class GFG {
    static int findMax(List<Tuple<Integer, Integer> > V,
                       int N, int M)
    {
        int ans = 0;
 
        // Stores whether an element
        // from the first array is used in mapping
        boolean[] is_paired = new boolean[N];
 
        // Contains mapping in sorted form
        List<HashSet<Integer> > mapping = new ArrayList<>();
        for (int i = 0; i <= N; i++) {
            mapping.add(new HashSet<Integer>());
        }
 
        // Insert mappings in sorted form
        for (Tuple<Integer, Integer> tuple : V) {
            mapping.get(tuple.Item1).add(tuple.Item2);
        }
 
        // While there is always at least one element
        // which can be mapped to a unique element
        while (true) {
            int lowest = -1;
 
            // Finds element to be mapped
            for (int i = 1; i <= N; i++) {
                // There is mapping possible
                if (mapping.get(i).size() > 0) {
                    if (lowest == -1) {
                        lowest = i;
                    }
                    else if (mapping.get(i).size()
                             < mapping.get(lowest).size()) {
                        lowest = i;
                    }
                }
            }
 
            if (lowest == -1) {
                break;
            }
 
            // Element used in the mapping
            is_paired[lowest - 1] = true;
 
            int remove
                = Collections.max(mapping.get(lowest));
            mapping.get(lowest).remove(remove);
 
            // Delete all the mappings of used element
            for (int i = 1; i <= N; i++) {
                mapping.get(i).remove(remove);
                if (i == lowest) {
                    mapping.get(i).clear();
                }
            }
            ans++;
        }
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int N = 3;
        int M = 3;
        int[] arr1 = new int[] { 1, 2, 3 };
        int[] arr2 = new int[] { 1, 2, 3 };
 
        List<Tuple<Integer, Integer> > V = Arrays.asList(
            new Tuple<>(1, 1), new Tuple<>(2, 1),
            new Tuple<>(2, 2), new Tuple<>(3, 1),
            new Tuple<>(3, 2), new Tuple<>(3, 3));
 
        // Function call
        System.out.println(findMax(V, N, M));
    }
}


Python3




# Python3 Program to convert many to many mapping
# to maximum no of one to one mappings
# Returns the maximum number
# of one to one mappings between two arrays
def FindMax(V, N, M):
    ans = 0
     
    # Stores whether an element
    # from the first array is used in mapping
    is_paired = [False] * N
     
    # Contains mapping in sorted form
    mapping = [set() for i in range(N + 1)]
     
    # Insert mappings in sorted form
    for i in range(len(V)):
        mapping[V[i][0]].add(V[i][1])
     
    # While there is always at least one element
    # which can be mapped to a unique element
    while True:
        lowest = -1
     
        # Finds element to be mapped
        for i in range(1, N + 1):
     
            # There is mapping possible
            if len(mapping[i]) > 0:
                if lowest == -1:
                    lowest = i
                elif len(mapping[i]) < len(mapping[lowest]):
                    lowest = i
     
        if lowest == -1:
            break
     
        # Element used in the mapping
        is_paired[lowest - 1] = True
     
        remove = mapping[lowest].pop()
     
        # Delete all the mappings of used element
        for i in range(1, N + 1):
     
            mapping[i].discard(remove)
            if i == lowest:
                mapping[i].clear()
        ans += 1
    return ans
 
# Driver code
N = 3
M = 3
arr1 = [1, 2, 3]
arr2 = [1, 2, 3]
 
V = [(1, 1), (2, 1), (2, 2), (3, 1), (3, 2), (3, 3)]
 
print(FindMax(V, N, M))


C#




using System;
using System.Linq;
using System.Collections.Generic;
 
class GFG
{
  static int FindMax(List<Tuple<int, int>> V, int N, int M)
  {
    int ans = 0;
 
    // Stores whether an element
    // from the first array is used in mapping
    bool[] is_paired = new bool[N];
 
    // Contains mapping in sorted form
    List<HashSet<int>> mapping = new List<HashSet<int>>();
    for (int i = 0; i <= N; i++)
    {
      mapping.Add(new HashSet<int>());
    }
 
    // Insert mappings in sorted form
    foreach (var tuple in V)
    {
      mapping[tuple.Item1].Add(tuple.Item2);
    }
 
    // While there is always at least one element
    // which can be mapped to a unique element
    while (true)
    {
      int lowest = -1;
 
      // Finds element to be mapped
      for (int i = 1; i <= N; i++)
      {
        // There is mapping possible
        if (mapping[i].Count > 0)
        {
          if (lowest == -1)
          {
            lowest = i;
          }
          else if (mapping[i].Count < mapping[lowest].Count)
          {
            lowest = i;
          }
        }
      }
 
      if (lowest == -1)
      {
        break;
      }
 
      // Element used in the mapping
      is_paired[lowest - 1] = true;
 
      int remove = mapping[lowest].Last();
      mapping[lowest].Remove(remove);
 
      // Delete all the mappings of used element
      for (int i = 1; i <= N; i++)
      {
        mapping[i].Remove(remove);
        if (i == lowest)
        {
          mapping[i].Clear();
        }
      }
      ans++;
    }
    return ans;
  }
 
  // Driver code
  static void Main(string[] args)
  {
    int N = 3;
    int M = 3;
    int[] arr1 = new int[] { 1, 2, 3 };
    int[] arr2 = new int[] { 1, 2, 3 };
 
    List<Tuple<int, int>> V = new List<Tuple<int, int>>()
    {
      Tuple.Create(1, 1),
      Tuple.Create(2, 1),
      Tuple.Create(2, 2),
      Tuple.Create(3, 1),
      Tuple.Create(3, 2),
      Tuple.Create(3, 3),
    };
 
    // Function call
    Console.WriteLine(FindMax(V, N, M));
  }
}


Javascript




// JavaScript program to convert many to many mapping
// to maximum no of one to one mappings
 
// Returns the maximum number of one to one mappings between two arrays
function FindMax(V, N, M) {
let ans = 0;
// Stores whether an element
// from the first array is used in mapping
let is_paired = new Array(N).fill(false);
 
// Contains mapping in sorted form
let mapping = new Array(N + 1).fill(0).map(() => new Set());
 
// Insert mappings in sorted form
for (let i = 0; i < V.length; i++) {
    mapping[V[i][0]].add(V[i][1]);
}
 
// While there is always at least one element
// which can be mapped to a unique element
while (true) {
    let lowest = -1;
 
    // Finds element to be mapped
    for (let i = 1; i < N + 1; i++) {
 
        // There is mapping possible
        if (mapping[i].size > 0) {
            if (lowest === -1) {
                lowest = i;
            } else if (mapping[i].size < mapping[lowest].size) {
                lowest = i;
            }
        }
    }
 
    if (lowest === -1) {
        break;
    }
 
    // Element used in the mapping
    is_paired[lowest - 1] = true;
 
    let remove = mapping[lowest].values().next().value;
    mapping[lowest].delete(remove);
 
    // Delete all the mappings of used element
    for (let i = 1; i < N + 1; i++) {
        mapping[i].delete(remove);
        if (i === lowest) {
            mapping[i].clear();
        }
    }
    ans++;
}
return ans;
}
 
// Driver code
let N = 3;
let M = 3;
let arr1 = [1, 2, 3];
let arr2 = [1, 2, 3];
 
let V = [[1, 1], [2, 1], [2, 2], [3, 1], [3, 2], [3, 3]];
 
console.log(FindMax(V, N, M));


Output:

3

Time Complexity: O(N * x)         , as we are using nested loops for traversing N*x times. Where x is maximum no one to one mappings and N is the number of elements in the array.
Auxiliary Space: O(N), as we are using extra space for the map. Where N is the number of elements in the array.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads