滑动窗口的中位数

给定一个包含 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);
    }



}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值