使用CSharp实现滑动窗口中位数算法
时间: 2023-12-14 17:50:26 浏览: 64
以下是使用CSharp实现滑动窗口中位数算法的示例代码:
```
using System;
using System.Collections.Generic;
namespace SlidingWindowMedian
{
class Program
{
static void Main(string[] args)
{
int[] nums = { 1, 3, -1, -3, 5, 3, 6, 7 };
int k = 3;
double[] medians = MedianSlidingWindow(nums, k);
foreach (double median in medians)
{
Console.WriteLine(median);
}
Console.ReadKey();
}
public static double[] MedianSlidingWindow(int[] nums, int k)
{
List<double> medians = new List<double>();
SortedSet<int> minHeap = new SortedSet<int>();
SortedSet<int> maxHeap = new SortedSet<int>(Comparer<int>.Create((x, y) => y.CompareTo(x)));
for (int i = 0; i < nums.Length; i++)
{
if (i >= k)
{
if (minHeap.Contains(nums[i - k]))
{
minHeap.Remove(nums[i - k]);
}
else
{
maxHeap.Remove(nums[i - k]);
}
}
if (maxHeap.Count == 0 || nums[i] <= maxHeap.Max)
{
maxHeap.Add(nums[i]);
}
else
{
minHeap.Add(nums[i]);
}
if (maxHeap.Count > minHeap.Count + 1)
{
minHeap.Add(maxHeap.Max);
maxHeap.Remove(maxHeap.Max);
}
else if (minHeap.Count > maxHeap.Count)
{
maxHeap.Add(minHeap.Min);
minHeap.Remove(minHeap.Min);
}
if (i >= k - 1)
{
if (k % 2 == 0)
{
medians.Add(((double)maxHeap.Max + (double)minHeap.Min) / 2);
}
else
{
medians.Add((double)maxHeap.Max);
}
}
}
return medians.ToArray();
}
}
}
```
该算法使用两个堆,一个最大堆和一个最小堆,来维护滑动窗口。最大堆存储滑动窗口中较小的一半元素,最小堆存储滑动窗口中较大的一半元素。
当新元素进入滑动窗口时,先将其插入最大堆或最小堆中,然后调整堆,以保持最大堆和最小堆的大小平衡。如果最大堆中的元素数量超过了最小堆中的元素数量,就将最大堆中的最大元素转移到最小堆中,以保持平衡。
当滑动窗口大小为奇数时,中位数就是最大堆中的最大元素。当滑动窗口大小为偶数时,中位数就是最大堆中的最大元素和最小堆中的最小元素的平均值。
阅读全文