查找由给定元素频率形成的数组的中位数
给定一个数组A[] ,其中包含一个数组的N个元素及其在该数组中的频率(例如 arr[]),任务是找到给定元素和频率的数组的中值。
注意:数组的中位数是排序数组中间的元素
例子:
Input: A[] = { {1, 2}, {4, 2}, {5, 1} }
Output: 4
Explanation: The array whose elements are given is {1, 1, 4, 4, 5}.
Therefore, the median of the array will be 4.
Input: A[] = { {3, 4}, {2, 3}, {9, 2} }
Output: 3
Explanation: The newly created array will be {2, 2, 2, 3, 3, 3, 3, 9, 9}.
Therefore the median of the array will be 3.
朴素方法:基本方法是创建数组,然后对数组进行排序并找到该数组的中间元素。
时间复杂度: O(M * log M) 其中 M 是 A[] 中给定的所有元素的频率之和。
辅助空间: O(M)
有效方法:由于A[]中存在的元素的频率总和可能非常大,因此构建数组是不可行的。这可以基于以下思想有效地解决:
Sort the array A[] based on the value of elements. Now calculate the total number of elements that will be in the array formed from these elements (say M). The element at M/2 th position is the median.
So iterate from the minimum elements and with the help of their frequencies find out the element and M/2 th position.
按照以下步骤实现上述想法:
- 将所有元素插入到一个map中,以元素为key,频率为value(一个map是根据key的值进行排序的,因此满足排序的需要)。
- 计算将在数组中的总元素。
- 从最小元素迭代并检查直到当前值的总元素是否与M/2相同:
- 如果相同,则当前元素是所需的中位数。
- 否则,增加元素的总数直到现在。
- 返回中位数。
下面是上述方法的实现。
C++
// C++ code to implement the approach
#include
using namespace std;
// Find median of the newly created array
int findMedian(vector > a, int n)
{
map m;
// Size of the newly created array
int totalsize = 0;
// Put all elements in the map
for (int i = 0; i < n; i++) {
int val = a[i][0];
int time = a[i][1];
m[val] += time;
totalsize += time;
}
// Find the element present at the middle
// of the newly created array
int meidanpos = totalsize / 2;
long long pos = 0;
for (auto it : m) {
// If the pos + current element times
// is greater than medianpos
// then return current element
if (pos + it.second > meidanpos) {
return it.first;
}
else {
pos += it.second;
}
}
}
// Driver Code
int main()
{
vector > A;
A = { { 1, 2 }, { 4, 2 }, { 5, 1 } };
int N = A.size();
// Function call
cout << findMedian(A, N);
return 0;
}
4
时间复杂度: O(N * logN)
辅助空间: O(N)