从给定数组中每个元素的左侧选择 K 个小偶数的方法数
给定一个由N个不同整数和一个正整数 K组成的数组arr[] ,任务是找到从每个第 i个位置的左侧选择K个元素的方法数,使得元素是偶数且小于arr[i] 。
例子:
Input: arr[] = {4, 2, 12, 33}, K = 2
Output: 0 0 1 3
Explanation:
- For arr[0](=4), there are 0, even elements less than arr[i]. Therefore, ways of selecting 2 elements from 0 element is equal to C(0, 2) = 0.
- For arr[1](=2), there are 0, even elements less than arr[i]. Therefore, ways of selecting 2 elements from 0 element is equal to C(0, 2) = 0.
- For arr[2](=12), there are 2, even elements less than arr[i]. Therefore, ways of selecting 2 elements from 2 elements is equal to C(2, 2) is 1.
- For arr[3](=33), there are 3, even elements less than arr[i]. Therefore, ways of selecting 2 elements from 3 elements is equal to C(3, 2) is 3.
Input: arr[] = {1, 2, 3}, K = 2
Output: 0 0 1
朴素方法:最简单的方法是遍历数组,为每个元素找到所有小于给定元素的数字,甚至在左侧,并检查计数是否小于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)