Sliding Window Median(滑动窗口的中位数)

http://www.lintcode.com/en/problem/sliding-window-median/?rand=true

public class Solution {
    /*
     * @param nums: A list of integers
     * @param k: An integer
     * @return: The median of the element inside the window at each moving
     */
    public List medianSlidingWindow(int[] nums, int k) {
        // write your code here
        //思路是我们使用两个有序的队列,一个小值,一个放大值,
        // 那么中位数就是小值队列里边的最大值,
        //每次保证小队列里边的数据个数要么比大队列的多一个,要么相等。
        PriorityQueue max = new PriorityQueue();
        //因为我们要操作的是小值队列的最大值,所以要把它逆序。
        PriorityQueue min = new PriorityQueue(Comparator.reverseOrder());
        //存放结果
        ArrayList list = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            //如果完全没有数据,优先添加到小队列里边
            if (min.size() == 0) {
                min.add(nums[i]);
            } else if (min.peek() > nums[i]) {
                //如果当前元素比小队列的最大值小,添加到小队列,
                min.add(nums[i]);
            } else {
//                否则添加到大队列
                max.add(nums[i]);
            }
            //判断是否有元素需要删除,
            if (i - k >= 0) {
                int delete = nums[i - k];
//                如果要删除的元素比小队列的最大值小或者相等。说明它在小队列里边,删除,
// 否则说明它在大队列里边
                if (min.peek() >= delete) {
                    min.remove(delete);
                } else {
                    max.remove(delete);
                }
            }
//            调整大队列和小队列的元素个数
            while (min.size() > max.size() + 1) {
                max.add(min.poll());
            }
            while (max.size() > min.size()) {
                min.add(max.poll());
            }
//            当有k个元素时,添加入结果集,直接使用小队列的最大值
            if (i >= k - 1) {
                list.add(min.peek());
            }
        }
        return list;
    }
}

你可能感兴趣的:(Sliding Window Median(滑动窗口的中位数))