# Ways to form n/2 pairs such that difference of pairs is minimum

Given an array *arr* of *N* integers, the task is to split the elements of the array into *N/2* pairs (each pair having 2 elements) such that the absolute difference between two elements of any pair is as minimum as possible.**Note:** *N* will always be even.

**Examples:**

Input:arr[] = {1, 7, 3, 8}Output:1

There is only one way to form pairs with

minimum difference, (7, 8) and (1, 3).

Input:arr[] = {1, 1, 1, 1, 2, 2, 2, 2}Output:9

Here all elements with value 2 will pair amongst themselves (3 ways possible) and all elements with value 1 will make pairs between them (3 ways possible)

Therefore, number of ways = 3 * 3 = 9

Input:arr[] = {2, 3, 2, 2}Output:3

**Approach:** This problem involves the fundamental principle of counting and some basic understanding of permutations and combinations.

Before going any further, let’s count the number of ways for the array = [3, 3]

Answer = 1, since only 1 combination is possible.

Now, lets modify the array to [3, 3, 3, 3]. The ways for this as discussed in the above examples are:

(1, 2), (3, 4)

(1, 3), (2, 4)

(1, 4), (2, 3)

Answer = 3 ways.

Further modifying the array to [3, 3, 3, 3, 3, 3]

(1, 2), (3, 4), (5, 6)

(1, 2), (3, 5), (4, 6)

(1, 2), (3, 6), (4, 5)

(1, 3), (2, 4), (5, 6)

(1, 3), (2, 5), (4, 6)

(1, 3), (2, 6), (4, 5)

(1, 4), (2, 3), (5, 6)

(1, 4), (2, 5), (3, 6)

(1, 4), (2, 6), (3, 5)

(1, 5), (2, 3), (4, 6)

(1, 5), (2, 4), (3, 6)

(1, 5), (2, 6), (3, 4)

(1, 6), (2, 3), (4, 5)

(1, 6), (2, 4), (3, 5)

(1, 6), (2, 5), (3, 4)

Answer = 15 ways.

Here we obtain a generalized result by simple observation. If there are *K* elements in the array that have the same value and K is **even**, then the number of ways to form pairs amongst them:

For size 2, count = 1 (1)

For size 4, count = 3 (1 * 3)

For size 6, count = 15 (1 * 3 * 5)

And so on.

Hence, number of ways to form pairs for size K where K is even = 1 * 3 * 5 * …. * (K-1)

We can precompute this result as follows. Let ways[] be the array such that ways[i] stores the number of ways for size ‘i’.

ways[2] = 1;

for(i = 4; i < 1e5 + 1; i += 2)

ways[i] = ways[i – 2] * (i – 1);For example, we consider array [3, 3, 3, 3, 3]

To compute the number of ways, we fix the first element with any of the remaining 5.

So we form one pair. Now 4 elements are left that can be paired inways[4]ways.

So number of ways would be5 * ways[4].

Now, it may not be necessary that counts may always be even in number. Therefore, if need to solve this for a general array, we need to do two things.

- Sort the array in ascending order.
- Analyze the count of each group having the same value.

Let our **array = [2, 3, 3, 3, 3, 4, 4, 4, 4, 4]**. This array is sorted.

- Considering element with value 4. Since there are 5 elements, 4 elements will pair amongst themselves in
**ways[4]**ways. The left out element can be chosen in 5 ways. The element left will have to pair with an element with value 3. This happens in**4 ways**since there are 4 elements with value 3. Therefore, one element of value 3 will be reserved to pair with an element of 4. So 3 elements with value 3 remain. 2 will pair amongst themselves in**ways[2]**ways and one 1 will pair with the element with value 2 in 1 way. Again, the lone element will be selected in 3 ways. - Therefore from point 1, number of ways will be :
ways[4] * 5 * 4 * ways[2] * 3 * 1 = 180

Below is the implementation of the above approach:

## C++

`// C++ implementation of the above approach` `#include <bits/stdc++.h>` ` ` `#define mp make_pair` `#define pb push_back` `#define S second` `#define ll long long` ` ` `using` `namespace` `std;` ` ` `// Using mod because the number` `// of ways might be very large` `const` `int` `mod = 1000000007;` ` ` `const` `int` `MAX = 100000;` ` ` `// ways is serving the same` `// purpose as discussed` `ll ways[MAX + 1];` ` ` `void` `preCompute()` `{` ` ` `// pairing up zero people` ` ` `// requires one way.` ` ` `ways[0] = 1LL;` ` ` `ways[2] = 1LL;` ` ` `for` `(` `int` `i = 4; i <= MAX; i += 2) {` ` ` `ways[i] = (1LL * (i - 1) * ways[i - 2]) % mod;` ` ` `}` `}` ` ` `void` `countWays(` `int` `* arr, ` `int` `n)` `{` ` ` ` ` `// map count stores count of s.` ` ` `map<` `int` `, ` `int` `> count;` ` ` `for` `(` `int` `i = 0; i < n; i++)` ` ` `count[arr[i]]++;` ` ` ` ` `vector<pair<` `int` `, ` `int` `> > count_vector;` ` ` `map<` `int` `, ` `int` `>::iterator it;` ` ` `for` `(it = count.begin(); it != count.end(); it++) {` ` ` `count_vector.pb(mp(it->first, it->second));` ` ` `}` ` ` ` ` `// vector count_vector stores a` ` ` `// pair < value, count of value>` ` ` ` ` `// sort according to value` ` ` `sort(count_vector.begin(), count_vector.end());` ` ` ` ` `ll ans = 1;` ` ` ` ` `// Iterating backwards.` ` ` `for` `(` `int` `i = count_vector.size() - 1; i > 0; i--) {` ` ` ` ` `int` `current_count = count_vector[i].S;` ` ` `int` `prev_count = count_vector[i - 1].S;` ` ` ` ` `// Checking if current count is odd.` ` ` `if` `(current_count & 1) {` ` ` ` ` `// if current count = 5, multiply ans by ways[4].` ` ` `ans = (ans * ways[current_count - 1]) % mod;` ` ` ` ` `// left out person will be selected` ` ` `// in current_count ways` ` ` `ans = (ans * current_count) % mod;` ` ` ` ` `// left out person will pair with previous` ` ` `// person in previous_count ways` ` ` `ans = (ans * prev_count) % mod;` ` ` ` ` `/* if previous count is odd,` ` ` `* then multiply answer by ways[prev_count-1].` ` ` `* since one has already been reserved,` ` ` `* remaining will be even.` ` ` `* reduce prev_count = 0, since we don't need it now.*/` ` ` `if` `(prev_count & 1) {` ` ` `ans = (ans * ways[prev_count - 1]) % mod;` ` ` `count_vector[i - 1].S = 0;` ` ` `}` ` ` `else` `{` ` ` ` ` `/* if prev count is even, one will be reserved,` ` ` `* therefore decrement by 1.` ` ` `* In the next iteration, prev_count will become odd` ` ` `* and it will be handled in the same way.*/` ` ` `count_vector[i - 1].S--;` ` ` `}` ` ` `}` ` ` `else` `{` ` ` ` ` `/* if current count is even,` ` ` `* then simply multiply ways[current_count]` ` ` `* to answer.*/` ` ` `ans = (ans * ways[current_count]) % mod;` ` ` `}` ` ` `}` ` ` ` ` `/* multiply answer by ways[first__count] since` ` ` `that is left out, after iterating the array.*/` ` ` `ans = (ans * ways[count_vector[0].S]) % mod;` ` ` `cout << ans << ` `"\n"` `;` `}` ` ` `// Driver code` `int` `main()` `{` ` ` `preCompute();` ` ` `int` `arr[] = { 2, 3, 3, 3, 3, 4, 4, 4, 4, 4 };` ` ` `int` `n = ` `sizeof` `(arr) / ` `sizeof` `(arr[0]);` ` ` `countWays(arr, n);` ` ` `return` `0;` `}` |

## Python3

`# Python3 implementation of the ` `# above approach ` `from` `collections ` `import` `defaultdict` ` ` `# Using mod because the number ` `# of ways might be very large ` `mod ` `=` `1000000007` `MAX` `=` `100000` ` ` `# ways is serving the same ` `# purpose as discussed ` `ways ` `=` `[` `None` `] ` `*` `(` `MAX` `+` `1` `) ` ` ` `def` `preCompute(): ` ` ` ` ` `# pairing up zero people ` ` ` `# requires one way. ` ` ` `ways[` `0` `] ` `=` `1` ` ` `ways[` `2` `] ` `=` `1` ` ` `for` `i ` `in` `range` `(` `4` `, ` `MAX` `+` `1` `, ` `2` `): ` ` ` `ways[i] ` `=` `((` `1` `*` `(i ` `-` `1` `) ` `*` ` ` `ways[i ` `-` `2` `]) ` `%` `mod)` ` ` `def` `countWays(arr, n): ` ` ` ` ` `# map count stores count of s. ` ` ` `count ` `=` `defaultdict(` `lambda` `:` `0` `)` ` ` `for` `i ` `in` `range` `(` `0` `, n): ` ` ` `count[arr[i]] ` `+` `=` `1` ` ` ` ` `count_vector ` `=` `[] ` ` ` `for` `key ` `in` `count: ` ` ` `count_vector.append([key, count[key]]) ` ` ` ` ` `# vector count_vector stores a ` ` ` `# pair < value, count of value> ` ` ` ` ` `# sort according to value ` ` ` `count_vector.sort() ` ` ` `ans ` `=` `1` ` ` ` ` `# Iterating backwards. ` ` ` `for` `i ` `in` `range` `(` `len` `(count_vector) ` `-` `1` `, ` `-` `1` `, ` `-` `1` `): ` ` ` ` ` `current_count ` `=` `count_vector[i][` `1` `] ` ` ` `prev_count ` `=` `count_vector[i ` `-` `1` `][` `1` `] ` ` ` ` ` `# Checking if current count is odd. ` ` ` `if` `current_count & ` `1` `: ` ` ` ` ` `# if current count = 5, multiply` ` ` `# ans by ways[4]. ` ` ` `ans ` `=` `(ans ` `*` `ways[current_count ` `-` `1` `]) ` `%` `mod ` ` ` ` ` `# left out person will be selected ` ` ` `# in current_count ways ` ` ` `ans ` `=` `(ans ` `*` `current_count) ` `%` `mod ` ` ` ` ` `# left out person will pair with previous ` ` ` `# person in previous_count ways ` ` ` `ans ` `=` `(ans ` `*` `prev_count) ` `%` `mod ` ` ` ` ` `# if previous count is odd, ` ` ` `# then multiply answer by ways[prev_count-1]. ` ` ` `# since one has already been reserved, ` ` ` `# remaining will be even. ` ` ` `# reduce prev_count = 0, since we` ` ` `# don't need it now.` ` ` `if` `prev_count & ` `1` `:` ` ` `ans ` `=` `(ans ` `*` `ways[prev_count ` `-` `1` `]) ` `%` `mod ` ` ` `count_vector[i ` `-` `1` `][` `1` `] ` `=` `0` ` ` ` ` `else` `:` ` ` ` ` `# if prev count is even, one will be ` ` ` `# reserved, therefore decrement by 1. ` ` ` `# In the next iteration, prev_count ` ` ` `# will become odd and it will be ` ` ` `# handled in the same way.` ` ` `count_vector[i ` `-` `1` `][` `1` `] ` `-` `=` `1` ` ` ` ` `else` `:` ` ` ` ` `# if current count is even, then simply` ` ` `# multiply ways[current_count] to answer.` ` ` `ans ` `=` `(ans ` `*` `ways[current_count]) ` `%` `mod ` ` ` ` ` `# multiply answer by ways[first__count] since ` ` ` `# that is left out, after iterating the array.` ` ` `ans ` `=` `(ans ` `*` `ways[count_vector[` `0` `][` `1` `]]) ` `%` `mod ` ` ` `print` `(ans) ` ` ` `# Driver code ` `if` `__name__ ` `=` `=` `"__main__"` `:` ` ` ` ` `preCompute() ` ` ` `arr ` `=` `[` `2` `, ` `3` `, ` `3` `, ` `3` `, ` `3` `, ` `4` `, ` `4` `, ` `4` `, ` `4` `, ` `4` `] ` ` ` `n ` `=` `len` `(arr)` ` ` `countWays(arr, n) ` ` ` `# This code is contributed by Rituraj Jain` |

**Output:**

180

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more, please refer **Complete Interview Preparation Course****.**

In case you wish to attend **live classes **with experts, please refer **DSA Live Classes for Working Professionals **and **Competitive Programming Live for Students**.