滑动窗口的中位数 LintCode

    滑动窗口的中位数  LintCode.com  

  1. 题目给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中滑动这个窗口,找到数组中每个窗口内的中位数。(如果数组个数是偶数,则在该窗口排序数字后,返回第 N/2 个数字。

  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;

  3.   算法:

    我的算法利用了冒泡排序的思想,用一个数组存储滑动窗口里的元素,并且时刻保持这个数组有序。在窗口滑动后,用二分查找法找到移出窗口的元素在这个数组的位置,然后将移入窗口的元素加入这个位置,通过与前面或后面的元素多次比较移动使数组重新有序(冒泡排序的思想)。

    时间复杂度:O(n)= n(log(n)+n) = n*n;

    ps:网上有利用堆来实现的,但是对于我来说很难想到,经过测试我的代码所用时间和利用堆来实现的是差不多的。(虽然它的时间复杂度好像是n*log n)。

      另外,新手写博客,有做的不好的地方请留言。

  Java 源代码:

 1 public static ArrayList<Integer> medianSlidingWindow(int[] nums, int k) {
 2         ArrayList<Integer> list = new ArrayList<Integer>();
 3         if(k==0||nums==null)   //窗口大小为0或数组为空则返回null;
 4             return null;
 5         int[] temp = new int[k];    //用来存储滑动窗口的元素,并且排序。
 6         for(int i=0;i<k;i++)    //先初始化temp;
 7             temp[i] = nums[i];
 8         Arrays.sort(temp);    //用Java内置方法对数组排序。
 9         list.add(temp[(k-1)/2]);    //获得第一个滑动窗口的中位数
10         int left = 0;    //滑动窗口的左边。
11         int right = k-1;    //滑动窗口的右边。
12         /*
13          * 窗口开始滑动
14          */
15         while(right<nums.length-1){    
16             int index = Arrays.binarySearch(temp, nums[left++]);    //用二分查找找到滑出的元素在temp的位置。
17             temp[index] = nums[++right];    //将划入的元素放在滑出的元素的位置上。
18             while(index>0){    //  index》0   表示元素向左移有位置。
19                 if(temp[index]<temp[index-1]){    //如果元素左边的元素大于他,则向左移,否则直接退出循环。
20                     int t = temp[index];
21                     temp[index] = temp[index-1];
22                     temp[index-1] = t;
23                     index--;
24                 }else
25                     break;
26             }
27             while(index<k-1){    //  index《k-1   表示元素向右移有位置。
28                 if(temp[index]>temp[index+1]){    //如果元素右边的元素小他,则向右移,否则直接退出循环。
29                     int t = temp[index];
30                     temp[index] = temp[index+1];
31                     temp[index+1] = t;
32                     index++;
33                 }else
34                     break;
35             }
36             list.add(temp[(k-1)/2]);
37         }
38         return list;
39     }

 

转载于:https://www.cnblogs.com/xfcnbkk/p/7246710.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值