k 大小子集,max 和 min 之间的最大差异为 d
C++
// C++ code to find no. of subsets with
// maximum difference d between max and
#include
using namespace std;
// function to calculate factorial of a numb
int fact(int i)
{
if (i == 0)
return 1;
return i * fact(i - 1);
}
int ans(int a[], int n, int k, int x)
{
if (k > n || n < 1)
return 0;
sort(a, a + n);
int count = 0;
int j = 1;
int i = 0;
int kfactorial = fact(k);
while (j <= n) {
while (j < n && a[j] - a[i] <= x) {
j++;
}
if ((j - i) >= k) {
count = count
+ fact(j - i)
/ (kfactorial * fact(j - i - k));
}
else {
i++;
j++;
continue;
}
if (j == n)
break;
while (i < j && a[j] - a[i] > x) {
i++;
}
if ((j - i) >= k) {
count = count
- fact(j - i)
/ (kfactorial * fact(j - i - k));
}
}
return count;
}
// driver program to test the above
// function
int main()
{
int arr[] = { 1, 12, 9, 2, 4, 2, 5, 8, 4, 6 },
k = 3,x = 5;
int n = sizeof(arr) / sizeof(arr[0]);
cout << ans(arr, n, k, x);
return 0;
}
// This code is contributed by Vishakha Chauhan
C++
// 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
// 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
# 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#
// 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.
PHP
$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;
?>
Javascript
52
给定一个数组和两个整数 k 和 d,求这个大小为 k 的数组的子集数,其中子集的最大和最小数之差最多为 d。
例子:
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
朴素的方法:找到所有大小为 k 的子集,并为每个子集找到最大和最小元素之间的差异。如果差值小于或等于 d,则计算它们。
有效的方法:
1)排序:首先对数组进行升序排序。现在,假设我们想为每个第 i个元素找出所需子集的数量,其中整数 a[i] 作为该子集的最小元素存在。这样一个子集中的最大值永远不会超过 a[i] + d 。
2)找到最大索引 j :我们可以在这个数组上对每个 i 应用二进制搜索,以找到最大索引 j,使得 a[j] <= a[i]+d 。现在,任何包含 a[i] 和范围 i+1…j 中的任何其他元素的子集都将成为必需的子集,因为元素 a[i] 是该子集的最小值,并且任何其他元素与 a[ i] 总是小于等于 d。
3)应用基本组合公式:现在我们要找到所需的大小为 k 的子集的数量。当您必须从给定的 n 个数字中选择 r 个项目时,这将使用基本的组合公式。同样,我们需要从已经包含 a[i] 的 (ji) 个元素中选择 (k-1) 个数,a[i] 是每个子集中的最小数。每个第 i个元素的这个过程的总和将是最终答案。
在这里,我使用了一种简单的递归方法来查找数字的阶乘,也可以使用动态规划来查找它。
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++
// 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
// 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
# 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#
// 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.
PHP
$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;
?>
Javascript
20
输出:
20