📌  相关文章
📜  包含 A[i] 正好 B[i] 次的数组中的第 K 个最小元素

📅  最后修改于: 2021-09-03 04:20:27             🧑  作者: Mango

给定两个数组A[]B[]N 个正整数和一个整数K 组成,任务是在通过从数组A[] 中取出第 i元素而形成的数组中找到第 K最小元素 B[i ]次。如果不存在这样的元素,则打印-1

例子:

朴素的方法:最简单的方法是迭代范围[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]。
  • 初始化一个变量,比如sum0,以将前缀 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