我试图使用有序集解决运行中位数问题(在hackerrank上)。只有它的元素才能正确排序。
在此处查看此行动:http://rextester.com/NGBN25779
public class RunningMedian{
List<int> list = new List<int>();
SortedSet<int> sorted = new SortedSet<int>();
public void Add(int num){
list.Add(num);
sorted.Add(num);
}
public double MedianNotWorking(){
return GetMedian(sorted.ToArray());
}
public double MedianWorking(){
int[] arr = list.ToArray();
Array.Sort(arr);
return GetMedian(arr);
}
public double GetMedian(int[] arr){
int idx = list.Count / 2;
if(arr.Length % 2 == 0){
return (double)((double)(arr[idx] + arr[idx-1]) / 2);
}else{
return arr[idx];
}
}
}
static void Main(String[] args) {
int n = Convert.ToInt32(Console.ReadLine());
int[] a = new int[n];
RunningMedian heap = new RunningMedian();
for(int i = 0; i < n; i++){
a[i] = Convert.ToInt32(Console.ReadLine());
heap.Add(a[i]);
//double median = heap.GetMedian();
double median = heap.MedianNotWorking();
Console.WriteLine(median.ToString("F1"));
}
}
在大多数情况下,有序集合确实有效。然而,在较大的输入尺寸下,它开始给出错误的答案。它可能不是问题的最佳解决方案,但我很好奇它为什么会失败。 C#没有最小堆/优先级队列,为什么不能将排序集用作替代?
*编辑包含来自hackerrank的完整代码。
这是一个输入文件。 输入 http://textuploader.com/dovni
预期 http://textuploader.com/dovnb
输出 http://textuploader.com/dovwj
冲突出现在最后
预期 (跳过1-364) 54240.0 54576.5 54913.0 54576.5 54240.0
结果 (跳过1-364) 54240.0 54576.5 54913.0 54963.0 54576.5
答案 0 :(得分:2)
SortedSet
个集合根据定义仅包含唯一值。但是,您的输入文件包含数字21794
两次,这意味着第二个21794
条目未添加到您的SortedSet
。因此,您的有序集合将包含的值少于列表,您的整个算法将不再起作用。
答案 1 :(得分:0)
通常,这可以通过为SortedSet比较定义新的IComparator行为来实现。对于最小优先级队列,将如下所示:
public class PriorityQueue<K,V> where K : IComparable
where V : IComparable
{
private SortedSet<Node<K,V>> _set;
private readonly int _amount;
public PriorityQueue(int amount)
{
_set = new SortedSet<Node<K,V>>(new PriorityComparer<K,V>());
_amount = amount;
}
public void Add(Node<K,V> value)
{
if (_amount > _set.Count)
_set.Add(value);
else
{
if (_set.Max.Val.CompareTo(value.Val) == 1)
{
_set.Remove(_set.Max);
_set.Add(value);
}
}
}
public Node<K,V> ExtractMax()
{
var max = _set.Max;
_set.Remove(max);
return max;
}
public Node<K,V> ExtractMin()
{
var min = _set.Min;
_set.Remove(min);
return min;
}
public bool IsEmpty => _set.Count == 0;
}
public struct Node<K,V> where K : IComparable
where V : IComparable
{
public K Key;
public V Val;
public Node(K key, V val)
{
Val = val;
Key = key;
}
}
public class PriorityComparer<K,V> : IComparer<Node<K,V>> where K: IComparable
where V: IComparable
{
public int Compare(Node<K,V> i, Node<K,V> y)
{
var compareresult = i.Val.CompareTo(y.Val);
if (compareresult == 0)
return i.Key.CompareTo(y.Key);
return compareresult;
}
}