假定正在从数据流中读取整数。查找从第一个整数到最后一个整数到目前为止已读取的所有元素的中值。这也称为运行整数中位数。
给定的链接已经包含使用优先级队列解决此问题的方法。
但是,以下解决方案使用相同的概念,但是实现是通过使用集来实现的。
在此解决方案中,我们将在长度均匀的情况下打印较小的中位数,而不是取其平均值。
例子:
Input: arr[] = {-10, 14, 11, -5, 7}
Output: -10 -10 11 -5 7
Input: arr[] = {2, -5, 14}
Output: 2 -5 2
方法:
- 按升序创建两个多集g ,将存储上半部分,按降序存储s ,以存储数组arr []的下半部分。
- 将第一个元素插入s中。并用该值初始化中位数。
- 对于数组x的每个其他元素。检查两个集合的大小:
- 当size(s)> size(g)时:如果x>中位数,则将s的第一个元素插入g并从s中删除该元素,然后将x插入s 。否则将x插入g 。
- 当size(s)
:如果x <中位数,则将g的第一个元素插入s并从g中删除该元素,然后将x插入g 。否则将x插入s 。 - 当size(s)= size(g)时:如果x>中位数。将x插入s 。否则将x插入g 。
下面是上述方法的实现:
// C++ program to find running median for
// a stream of integers using Set
#include
using namespace std;
// Function to print the running median
// for the array arr[]
void printRunningMedian(int arr[], int n)
{
// Multiset is used to handle duplicates
// Multiset g for storing upper half
// (ascending order)
// The first element will be the smallest)
multiset g;
// Multiset s for storing lower half
// (descending order). The first element
// will be the largest
multiset > s;
s.insert(arr[0]);
// Initialise median with the first element
int med = arr[0];
printf("%d ", med);
for (int i = 1; i < n; i++) {
// Only add elements to upper half if
// its size less then the size of the
// lower half (maintain only difference
// of 1)
if (s.size() > g.size()) {
if (arr[i] < med) {
int temp = *s.begin();
s.erase(s.begin());
g.insert(temp);
s.insert(arr[i]);
}
else
g.insert(arr[i]);
med = *s.begin() > *g.begin() ?
*g.begin() : *s.begin();
}
// Only add elements to lower half if
// it's size less then the size of the
// upper half (maintain only difference
// of 1)
else if (s.size() < g.size()) {
if (arr[i] > med) {
int temp = *g.begin();
g.erase(g.begin());
s.insert(temp);
g.insert(arr[i]);
}
else
s.insert(arr[i]);
med = *s.begin() > *g.begin() ?
*g.begin() : *s.begin();
}
// If sizes are same
else {
if (arr[i] > med) {
g.insert(arr[i]);
med = *g.begin();
}
else {
s.insert(arr[i]);
med = *s.begin();
}
}
printf("%d ", med);
}
printf("\n");
}
// Driver code
int main()
{
int arr[] = { -10, 14, 11, -5, 7 };
int n = sizeof(arr) / sizeof(arr[0]);
printRunningMedian(arr, n);
return 0;
}
输出:
-10 -10 11 -5 7