难点在于【有序】,即每一个新的窗口都需要重新排序。但由于每次窗口移动的位数是规律的,因此不必每次对新的窗口集合全排,而只需要考虑移除旧窗口的数,并如何高效地把新窗口的数插入合适的地点。我是通过二分查找的方式寻找有效插入地点的(特殊情况直接插入即可)。
public class Solution {
public double[] MedianSlidingWindow(int[] nums, int k) {
int len = nums.Length - k + 1;
double[] res = new double[len];
List<int> list = new List<int>();
for(int i = 0; i < k; i ++)
list.Add(nums[i]);
list.Sort();
for(int i = 0; i < len; i ++)
{
if(i > 0)
{
list.Remove(nums[i-1]);
Insert(nums[i+k-1],list);
}
if(k % 2 == 0)
res[i] = (double)((double)list[k / 2 - 1] + (double)list[k / 2]) / 2;
else
res[i] = list[k / 2];
}
return res;
}
private void Insert(int target,List<int> list)
{
int count = list.Count();
int s = 0, e = count-1;
if(count == 0 || target >= list[e])
{
list.Add(target);
return;
}
if(target <= list[0])
{
list.Insert(0,target);
return;
}
while(s <= e)
{
int mid = (s + e) / 2;
if(list[mid] < target)
s = mid + 1;
else if(list[mid] > target)
e = mid - 1;
else
{
list.Insert(mid,target);
return;
}
}
list.Insert(s,target);
}
}