给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中滑动这个窗口,找到数组中每个窗口内的中位数。(如果数组个数是偶数,则在该窗口排序数字后,返回第 N/2 个数字。)
样例
对于数组 [1,2,7,8,5]
, 滑动大小 k = 3 的窗口时,返回 [2,7,7]
最初,窗口的数组是这样的:
[ | 1,2,7 | ,8,5]
, 返回中位数 2
;
接着,窗口继续向前滑动一次。
[1, | 2,7,8 | ,5]
, 返回中位数 7
;
接着,窗口继续向前滑动一次。
[1,2, | 7,8,5 | ]
, 返回中位数 7
;
import java.util.*;
/**
* Created by wb-xzc291800 on 2017/6/30.
*/
public class Solution {
int mid = 0;
/**
* @param nums: A list of integers.
* @return: The median of the element inside the window at each moving.
*/
public ArrayList<Integer> medianSlidingWindow(int[] nums, int k) {
mid = getMid(k);
ArrayList<Integer> a = new ArrayList<Integer>();
if (k == 0 || nums.length < mid) {
return a;
} else if (nums.length == mid || (nums.length > mid && nums.length < k)) {
a.add(nums[mid - 1]);
return a;
} else if (1 == k) {
for (int i : nums) {
a.add(i);
}
return a;
} else if (2 == k) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
a.add(nums[i + 1]);
} else {
a.add(nums[i]);
}
}
return a;
}
LinkedList<Integer> sub = subArray(nums, k);
a.add(sub.get(mid - 1));
for (int i = k; i < nums.length; i++) {
start = 0;
end = 0;
insert(sub, nums[i]);
sub.remove(sub.indexOf(nums[i - k]));
a.add(sub.get(mid - 1));
}
return a;
}
int getMid(int k) {
int mid = 0;
if (k % 2 == 1) {
mid = (k + 1) / 2;
} else {
mid = k / 2;
}
return mid;
}
/**
* 截取首个视窗数组,并且排序
* @param nums
* @param k
* @return
*/
LinkedList<Integer> subArray(int[] nums, int k) {
LinkedList<Integer> ret = new LinkedList<Integer>();
for (int i = 0; i < k; i++) {
ret.add(nums[i]);
}
Collections.sort(ret);
return ret;
}
int start = 0;
int end = 0;
/**
* 二分法查找插入值
* @param linkedList
* @param val
*/
void insert(LinkedList<Integer> linkedList, int val) {
if (end == 0) {
end = linkedList.size() - 1;
}
if (end - start <= 1) {
if (linkedList.get(start) >= val) {
linkedList.add(start, val);
return;
}
if (linkedList.get(end) <= val || end == linkedList.size()) {
linkedList.addLast(val);
return;
}
linkedList.add(end,val);
return;
}
int mid = (start + end) / 2;
int x = linkedList.get(mid);
if (x > val) {
end = mid;
} else {
start = mid;
}
insert(linkedList, val);
}
}