# 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 = 9Input: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 in

ways[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 :

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

**Time Complexity: **O(nlogn)

**Auxiliary Space: **O(MAX + n)