Chr*_*ris 8 java algorithm median
对于一个映射,其中键表示一个序列的数量,并且值是计数这个数字在序列中出现的频率,java中的算法实现如何计算中值?
例如:
1,1,2,2,2,2,3,3,3,4,5,6,6,6,7,7
Run Code Online (Sandbox Code Playgroud)
在地图中:
Map<Int,Int> map = ...
map.put(1,2)
map.put(2,4)
map.put(3,3)
map.put(4,1)
map.put(5,1)
map.put(6,3)
map.put(7,2)
double median = calculateMedian(map);
print(median);
Run Code Online (Sandbox Code Playgroud)
会导致:
> print(median);
3
>
Run Code Online (Sandbox Code Playgroud)
所以我要找的是一个java实现calculateMedian.
线性时间
如果您知道数字的总数(在您的情况下为16),则可以从地图的开头或结尾开始,对计数进行求和,直到到达第(n / 2)个元素为止,或者总和等于第floor(n / 2)个元素和第ceil(n / 2)个元素的平均值 = 中位数。
如果您不知道总数,则必须至少对所有这些进行一次检查。
亚线性时间
如果您可以决定数据结构并可以进行预处理,请参阅维基百科有关选择算法的信息,甚至可以得到亚线性算法。如果您对数据的分布有所了解,还可以获得次线性时间。
编辑:因此,假设我们有一个计数序列,我们可以做的是
key -> count配对时会维护另一张地图-key -> running_total这将使内存使用量增加一倍,但对于中位数将提供O(log n)性能,对于total_count将提供O(1)。
使用番石榴:
Multiset<Integer> values = TreeMultiset.create();
Collections.addAll(values, 1,1,2,2,2,2,3,3,3,4,5,6,6,6,7,7);
Run Code Online (Sandbox Code Playgroud)
现在,您的问题的答案是:
return Iterables.get(values, (values.size() - 1) / 2);
Run Code Online (Sandbox Code Playgroud)
真。而已。 (或者检查大小是否均等,并精确计算两个中心值。)
如果计数特别大,则使用多集entrySet并保持运行总和会更快,但是最简单的方法通常很好。
SortedMap,即 aTreeMap| 归档时间: |
|
| 查看次数: |
3015 次 |
| 最近记录: |