GFG App
Open App
Browser
Continue

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

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 ` `using` `namespace` `std;` ` `  `// Returns the maximum number` `// of one to one mappings between two arrays` `int` `FindMax(vector >& 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 > 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 >` `        ``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 {`   `    ``// 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 > 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 > mapping = ``new` `ArrayList<>();` `        ``for` `(``int` `i = ``0``; i <= N; i++) {` `            ``mapping.add(``new` `HashSet());` `        ``}`   `        ``// Insert mappings in sorted form` `        ``for` `(Tuple 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 > 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> 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> mapping = ``new` `List>();` `    ``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> V = ``new` `List>()` `    ``{` `      ``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.

My Personal Notes arrow_drop_up