📌  相关文章
📜  从给定数组中每个元素的左侧选择 K 个小偶数的方法数

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

从给定数组中每个元素的左侧选择 K 个小偶数的方法数

给定一个N个不同整数和一个正整数 K组成数组arr[] 任务是找到从每个第 i位置的左侧选择K个元素的方法数,使得元素是偶数且小于arr[i]

例子:

朴素方法:最简单的方法是遍历数组,为每个元素找到所有小于给定元素的数字,甚至在左侧,并检查计数是否小于K,然后打印0 ,否则,使用组合学找出方法的数量。

时间复杂度: O(N 2 )
辅助空间: O(1)

高效方法:上述方法可以通过使用有序集数据结构进行优化。请按照以下步骤解决问题:

  • 初始化一个有序集,比如S来存储偶数的值。
  • 另外,初始化一个数组,比如ans[],来存储结果。
  • 使用变量i遍历数组arr[]并执行以下步骤:
    • 如果集合S的大小为0 ,则将0分配给ans[i]并继续。
    • 使用集合S中的 order_of_key()函数查找小于arr[i]的元素的计数,并将其存储在变量中,例如count
    • 现在将从count i, e C(count, K)中选择K个元素的方式数分配给ans[i]。
  • 最后,完成以上步骤后,打印数组ans[i]。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
// Policy based data structure
#include 
#include 
using namespace __gnu_pbds;
  
#define ordered_set                              \
    tree, rb_tree_tag, \
         tree_order_statistics_node_update>
  
// NCR formula to find number
// of ways
int ncr(int n, int r)
{
    if (r == 0 || n == r) {
        return 1;
    }
    return ncr(n - 1, r) + ncr(n - 1, r - 1);
}
  
// Function to find the number of ways
// of selecting K smaller even element
// on the left of each element
void numberofSmallerElementsInLeft(int arr[], int N, int K)
{
    // Set to store even elements
    ordered_set S;
  
    // Stores answer for each element
    int ans[N];
  
    for (int i = 0; i < N; i++) {
        // Set is empty
        if (S.size() == 0)
            ans[i] = 0;
        else {
  
            // Finds the count of elements
            // less than arr[i]
            int count = S.order_of_key(arr[i]);
  
            // If count is 0
            if (count == 0)
                ans[i] = 0;
            // Else
            else {
  
                // Number of ways to choose k
                // elements from pos
                ans[i] = ncr(count, K);
            }
        }
  
        // If the element is even
        // insert it into S
        if (arr[i] % 2 == 0)
            S.insert(arr[i]);
    }
    // Print the result
    for (int i = 0; i < N; i++) {
        cout << ans[i] << " ";
    }
}
  
// Driver Code
int main()
{
  
    // Input
    int arr[] = { 4, 2, 12, 33 };
    int K = 2;
    int N = sizeof(arr) / sizeof(arr[0]);
  
    // Function Call
    numberofSmallerElementsInLeft(arr, N, K);
    return 0;
}


输出
0 0 1 3 

时间复杂度: O(N*log(N))
辅助空间: O(N)