给定两个数组A[]和B[]由N 个正整数和一个整数K 组成,任务是在通过从数组A[] 中取出第 i个元素而形成的数组中找到第 K个最小元素 B[i ]次。如果不存在这样的元素,则打印-1 。
例子:
Input: K = 4, A[] = {1, 2, 3}, B[] = {1, 2, 3}
Output: 3
Explanation:
The array obtained by taking A[0], B[0] (= 1) time, A[1], B[1] (= 2) times, A[2], B[2]( = 3) times is {1, 2, 2, 3, 3, 3}. Therefore, the 4th element of the array is 3.
Input: K = 4, A[] = {3, 4, 5}, B[] = {2, 1, 3}
Output: 3
Explanation:The array formed is {3, 3, 4, 5, 5, 5}. Therefore, the 4th element of the array i.e 5.
朴素的方法:最简单的方法是迭代范围[0, N – 1]并将数组第i个索引处的元素推送B[i]次到新数组中。最后,将数组升序排序后打印得到数组的第K个元素。
时间复杂度: O(N*log(N)),其中N是新数组中的元素数。
辅助空间: O(N)
高效的方法:可以通过使用频率数组来保持每个元素的计数来优化上述方法。请按照以下步骤解决问题:
- 找到数组 A[]的最大元素并将其存储在一个变量中,比如M 。
- 用 { 0 } 初始化一个数组,比如大小为M + 1 的freq[] ,以存储每个元素的频率。
- 使用变量i在范围[0, N-1] 中迭代:
- 在freq[A[i]] 中添加B[i]。
- 初始化一个变量,比如sum为0,以将前缀 sum 存储到特定索引。
- 使用变量迭代范围[0, N – 1] ,比如 i :
- 将freq[i]相加。
- 如果sum大于或等于K ,则返回i。
- 最后,返回-1。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the Kth smallest element
// that contains A[i] exactly B[i] times
int KthSmallest(int A[], int B[], int N, int K)
{
int M = 0;
// Traverse the given array
for (int i = 0; i < N; i++) {
M = max(A[i], M);
}
// Stores the frequency
// of every elements
int freq[M + 1] = { 0 };
// Traverse the given array
for (int i = 0; i < N; i++) {
freq[A[i]] += B[i];
}
// Initialize a variable to
// store the prefix sums
int sum = 0;
// Iterate over the range [0, M]
for (int i = 0; i <= M; i++) {
// Increment sum by freq[i]
sum += freq[i];
// If sum is greater
// than or equal to K
if (sum >= K) {
// Return the current
// element as answer
return i;
}
}
// Return -1
return -1;
}
// Driver Code
int main()
{
// Given Input
int A[] = { 3, 4, 5 };
int B[] = { 2, 1, 3 };
int N = sizeof(A) / sizeof(A[0]);
int K = 4;
// Function call
cout << KthSmallest(A, B, N, K);
return 0;
}
5
时间复杂度: O(N),其中N是数组A[]和B[] 的大小。
辅助空间: O(M),其中M是数组 A[]的最大元素。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live