📜  k 大小子集,max 和 min 之间的最大差异为 d

📅  最后修改于: 2022-05-13 01:57:50.654000             🧑  作者: Mango

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元素的这个过程的总和将是最终答案。
在这里,我使用了一种简单的递归方法来查找数字的阶乘,也可以使用动态规划来查找它。

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