k size subsets with maximum difference d between max and min

Given an array and two integers k and d, find the number of subsets of this array of size k, where difference between the maximum and minimum number of the subset is atmost d.

Examples:

```Input : a[] = [5, 4, 2, 1, 3],
k = 3, d = 5
Output : 10
Explanation:
{1,2,3}, {1,2,4}, {1,2,5}, {1,3,4}, {1,3,5},
{1,4,5}, {2,3,4}, {2,3,5}, {2,4,5}, {3,4,5}.
We can see each subset has atmost
difference d=5 between the minimum
and maximum element of each subset.
No of such subsets = 10

Input : a[] = [1, 2, 3, 4, 5, 6],
k = 3, d = 5
Output : 20
```

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive approach: Finding all the subsets of size k and for each subset find the difference between maximum and minimum element. If the difference is less than or equal to d, count them.

Efficient approach :
1) Sorting: First sort the array in increasing order. Now, assume we want to find out for each ith element, the number of required subsets in which integer a[i] is present as the minimum element of that subset. The maximum in such a subset will never exceed a[i] + d .
2) Find maximum index j : We can apply binary search over this array for each i, to find the maximum index j, such that a[j] <= a[i]+d . Now any subset that includes a[i] and any other elements from the range i+1…j will be a required subset as because element a[i] is the minimum of that subset, and the difference between any other element and a[i] is always less than equal to d.
3) Apply basic combinatorics formula : Now we want to find the number of required subsets of size k. This will be by using the basic formula of combination when you have to select r items from given n numbers. In the same way we need to choose (k-1) numbers from (j-i) elements already including a[i] which is the minimum number in each subset. The sum of this procedure for each ith element will be the final answer.
Here I have used a simple recursive way to find factorial of a number one can use dynamic programming as well to find it.

Illustration :
Input : a = [5, 4, 2, 1, 3],
k = 3, d = 5
Output : 10
Explanation:
Sorted array in ascending order : [1, 2, 3, 4, 5]

For a[0] = 1 as minimum element
No. of subset will be 6 which are {1, 2, 3}, {1, 2,
4}, {1, 2, 5}, {1, 3, 4}, {1, 3, 5}, {1, 4, 5}.

For a[1] = 2 as minimum element
No. of subset will be 3 which are {2, 3, 4}, {2,
3, 5}, {2, 4, 5}

For a[2] = 3 as minimum element
No. of subset will be 1 which is {3, 4, 5}
No other subset of size k = 3 will be formed
by taking a[3] = 4 or a[4] = 5 as minimum element

 `// C++ code to find no. of subsets with  ` `// maximum difference d between max and ` `// min of all K-size subsets function to ` `// calculate factorial of a number ` `#include ` `using` `namespace` `std; ` ` `  `int` `fact (``int` `n){ ` `    ``if` `(n==0) ` `        ``return` `1; ` `    ``else` `        ``return` `n * fact(n-1); ` `} ` ` `  `// function to count ways to select r ` `// numbers from n given numbers ` `int` `findcombination (``int` `n,``int` `r){ ` `    ``return``( fact(n) / (fact(n - r) * ` `                        ``fact(r))); ` `} ` ` `  `// function to return the total number  ` `// of required subsets : ` `// n is the number of elements in array ` `// d is the maximum difference between ` `// minimum and maximum element in each ` `// subset of size k  ` `int` `find(``int` `arr[], ``int` `n, ``int` `d, ``int` `k) ` `{ ` `    ``sort(arr,arr+n); ` `    ``int` `ans = 0, end = n, co = 0, ` `        ``start = 0; ` ` `  `    ``// loop to traverse from 0-n ` `    ``for` `(``int` `i = 0; i < n; i++) { ` ` `  `    ``int` `val = arr[i] + d; ` `     `  `    ``// binary search to get the position ` `    ``// which will be stored in start ` `     `  `    ``start = i; ` `    ``while` `(start < end - 1){ ` `        ``int` `mid = (start + end) / 2; ` ` `  `        ``// if mid value greater than ` `        ``// arr[i]+d do search in  ` `        ``// arr[start:mid] ` `        ``if` `(arr[mid] > val) ` `            ``end = mid; ` ` `  `        ``else` `            ``start = mid + 1; ` `    ``} ` `     `  `    ``if` `(start != n and arr[start]  ` `                       ``<= val) ` `            ``start += 1; ` ` `  `    ``int` `c = start-i; ` ` `  `    ``// if the numbers of elements 'c'  ` `    ``// is greater or equal to the given  ` `    ``// size k, then only subsets of  ` `    ``// required size k can be formed ` `    ``if` `(c >= k){ ` `        ``co += findcombination(c - 1, k - 1);} ` `    ``} ` `    ``return` `co; ` `} ` ` `  `// driver program to test the above ` `// function ` `int` `main() ` `{ ` `    ``int` `arr[] = {1, 2, 3, 4, 5, 6}, ` `        ``k = 3, d = 5;  ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]); ` `    ``cout << find(arr, n,d,k); ` `    ``return` `0; ` `} ` `// This code is contributed by Prerna Saini `

 `// Java code to find no. of subsets  ` `// with maximum difference d between ` `// max and min of all K-size subsets ` `import` `java.util.*; ` ` `  `class` `GFG { ` ` `  `// function to calculate factorial  ` `// of a number ` `static` `int` `fact (``int` `n){ ` `    ``if` `(n==``0``) ` `        ``return` `1``; ` `    ``else` `        ``return` `n * fact(n-``1``); ` `} ` ` `  `// function to count ways to select r ` `// numbers from n given numbers ` `static` `int` `findcombination(``int` `n, ``int` `r){ ` `    ``return``( fact(n) / (fact(n - r) *  ` `                           ``fact(r))); ` `} ` ` `  `// function to return the total number ` `// of required subsets : ` `// n is the number of elements in array ` `// d is the maximum difference between  ` `// minimum and maximum element in each ` `// subset of size k  ` `static` `int` `find(``int` `arr[], ``int` `n, ``int` `d, ` `                            ``int` `k) ` `{ ` `    ``Arrays.sort(arr); ` `    ``int` `ans = ``0``, end = n, co = ``0``, ` `        ``start = ``0``; ` ` `  `    ``// loop to traverse from 0-n ` `    ``for` `(``int` `i = ``0``; i < n; i++) { ` ` `  `    ``int` `val = arr[i] + d; ` `     `  `    ``// binary search to get the position ` `    ``// which will be stored in start ` `    ``start=i; ` `    ``while` `(start < end - ``1``){ ` `        ``int` `mid = (start + end) / ``2``; ` ` `  `        ``// if mid value greater than ` `        ``// arr[i]+d do search in  ` `        ``// arr[start:mid] ` `        ``if` `(arr[mid] > val) ` `            ``end = mid; ` `        ``else` `            ``start = mid+``1``; ` `        ``} ` `         `  `    ``if` `(start !=n && arr[start] <= val) ` `            ``start += ``1``; ` ` `  `        ``int` `c = start-i; ` ` `  `    ``// if the numbers of elements 'c' is ` `    ``// greater or equal to the given size k, ` `    ``// then only subsets of required size k ` `    ``// can be formed ` `    ``if` `(c >= k){ ` `        ``co += findcombination(c - ``1``, k - ``1``);} ` `    ``} ` `     `  `    ``return` `co; ` `} ` ` `  `// driver program to test the above function ` `public` `static` `void` `main(String[] args) ` `{ ` `    ``int` `arr[] = {``1``, ``2``, ``3``, ``4``, ``5``, ``6``}, k = ``3``, ` `        ``d = ``5``;  ` `    ``int` `n = arr.length; ` `    ``System.out.println(find(arr, n,d,k)); ` `} ` `} ` `// This code is contributed by Prerna Saini `

 `# Python code to find no. of subsets with maximum  ` `# difference d between max and min of all K-size  ` `# subsets function to calculate factorial of a  ` `# number ` `def` `fact (n): ` `    ``if` `(n``=``=``0``): ` `        ``return` `(``1``) ` `    ``else``: ` `        ``return` `n ``*` `fact(n``-``1``) ` ` `  `# function to count ways to select r numbers ` `# from n given numbers ` `def` `findcombination (n,r): ` `    ``return``( fact(n)``/``/``(fact(n``-``r)``*``fact(r))) ` ` `  `# function to return the total number of required  ` `# subsets : ` `# n is the number of elements in list l[0..n-1] ` `# d is the maximum difference between minimum and ` `#    maximum element in each subset of size k     ` `def` `find (a, n, d, k): ` ` `  `    ``# sort the list first in ascending order ` `    ``a.sort() ` `    ``(start, end, co) ``=` `(``0``, n, ``0``) ` ` `  `    ``for` `i ``in` `range``(``0``, n): ` `        ``val ``=` `a[i]``+` `d ` ` `  `        ``# binary search to get the position ` `        ``# which will be stored in start ` `        ``# such that a[start] <= a[i]+d ` `        ``start ``=` `i ` `        ``while` `(start< end``-``1``): ` `            ``mid ``=` `(start``+``end)``/``/``2` ` `  `            ``# if mid value greater than a[i]+d  ` `            ``# do search in l[start:mid] ` `            ``if` `(a[mid] > val): ` `                ``end ``=` `mid ` ` `  `            ``# if mid value less or equal to a[i]+d ` `            ``# do search in a[mid+1:end] ` `            ``else``: ` `                ``start ``=` `mid``+``1` ` `  `        ``if` `(start!``=``n ``and` `a[start]<``=``val): ` `            ``start ``+``=` `1` ` `  `        ``# count the numbers of elements that fall ` `        ``# in range i to start ` `        ``c ``=` `start``-``i ` ` `  `        ``# if the numbers of elements 'c' is greater ` `        ``# or equal to the given size k, then only ` `        ``# subsets of required size k can be formed ` `        ``if` `(c >``=` `k): ` `            ``co ``+``=` `findcombination(c``-``1``,k``-``1``) ` ` `  `    ``return` `co ` ` `  `# Driver code ` `n ``=` `6`  `# Number of elements ` `d ``=` `5`  `# maximum diff ` `k ``=` `3`  `# Size of subsets ` `print``(find([``1``, ``2``, ``3``, ``4``, ``5``, ``6``], n, d, k))   `

 `// C# code to find no. of subsets  ` `// with maximum difference d between ` `// max and min of all K-size subsets ` `using` `System; ` ` `  `class` `GFG { ` ` `  `    ``// function to calculate factorial  ` `    ``// of a number ` `    ``static` `int` `fact (``int` `n) ` `    ``{ ` `        ``if` `(n == 0) ` `            ``return` `1; ` `        ``else` `            ``return` `n * fact(n - 1); ` `    ``} ` `     `  `    ``// function to count ways to select r ` `    ``// numbers from n given numbers ` `    ``static` `int` `findcombination(``int` `n, ``int` `r) ` `    ``{ ` `        ``return``( fact(n) / (fact(n - r) *  ` `                               ``fact(r))); ` `    ``} ` `     `  `    ``// function to return the total number ` `    ``// of required subsets : ` `    ``// n is the number of elements in array ` `    ``// d is the maximum difference between  ` `    ``// minimum and maximum element in each ` `    ``// subset of size k  ` `    ``static` `int` `find(``int` `[]arr, ``int` `n, ``int` `d, ` `                                      ``int` `k) ` `    ``{ ` `        ``Array.Sort(arr); ` `         `  `        ``//int ans = 0,  ` `        ``int` `end = n, co = 0, ` `            ``start = 0; ` `     `  `        ``// loop to traverse from 0-n ` `        ``for` `(``int` `i = 0; i < n; i++)  ` `        ``{ ` `            ``int` `val = arr[i] + d; ` `             `  `            ``// binary search to get the ` `            ``// position which will be ` `            ``// stored in start ` `            ``start = i; ` `            ``while` `(start < end - 1){ ` `                ``int` `mid = (start + end) / 2; ` `         `  `                ``// if mid value greater than ` `                ``// arr[i]+d do search in  ` `                ``// arr[start:mid] ` `                ``if` `(arr[mid] > val) ` `                    ``end = mid; ` `                ``else` `                    ``start = mid+1; ` `                ``} ` `                 `  `            ``if` `(start !=n && arr[start] <= val) ` `                    ``start += 1; ` `         `  `                ``int` `c = start-i; ` `         `  `            ``// if the numbers of elements 'c' is ` `            ``// greater or equal to the given size k, ` `            ``// then only subsets of required size k ` `            ``// can be formed ` `            ``if` `(c >= k) ` `                ``co += findcombination(c - 1, k - 1); ` `        ``} ` `         `  `        ``return` `co; ` `    ``} ` `     `  `    ``// driver program to test the above function ` `    ``public` `static` `void` `Main() ` `    ``{ ` `        ``int` `[]arr = {1, 2, 3, 4, 5, 6}; ` `        ``int` `k = 3; ` `        ``int` `d = 5;  ` `        ``int` `n = arr.Length; ` `        ``Console.WriteLine(find(arr, n, d, k)); ` `    ``} ` `} ` ` `  `// This code is contributed by anuj_67. `

 ` ``\$val``) ` `            ``\$end` `= ``\$mid``; ` `  `  `        ``else` `            ``\$start` `= ``\$mid` `+ 1; ` `    ``} ` `      `  `    ``if` `(``\$start` `!= ``\$n` `&& ``\$arr``[``\$start``]  ` `                       ``<= ``\$val``) ` `            ``\$start` `+= 1; ` `  `  `    ``\$c` `= ``\$start``-``\$i``; ` `  `  `    ``// if the numbers of elements 'c'  ` `    ``// is greater or equal to the given  ` `    ``// size k, then only subsets of  ` `    ``// required size k can be formed ` `    ``if` `(``\$c` `>= ``\$k``){ ` `        ``\$co` `+= findcombination(``\$c` `- 1, ``\$k` `- 1);} ` `    ``} ` `    ``return` `\$co``; ` `} ` `  `  `// driver program to test the above ` `// function ` ` `  `    ``\$arr` `= ``array``(1, 2, 3, 4, 5, 6); ` `    ``\$k` `= 3; ` `    ``\$d` `= 5;  ` `    ``\$n` `= sizeof(``\$arr``) / sizeof(``\$arr``[0]); ` `    ``echo` `find(``\$arr``, ``\$n``,``\$d``,``\$k``); ` `    ``return` `0; ` `?> `

Output:
```20
```

This article is contributed by Sruti Rai . If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.