首页 > 试题广场 >

滑动窗口的中位数

[编程题]滑动窗口的中位数
  • 热度指数:1811 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

在实时计算中,数据流源源不断地流入计算单元,经常需要借助窗口来处理数据,其中有一类窗口为滑动窗口(Sliding Window),其特点是窗口长度固定,每次滑动一定的位移(slide

 

现给定一个数组 nums,有一个长度为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。注意你只可以看到在滑动窗口 k 内的数字,滑动位移大小slide=1,即滑动窗口每次只向右移动一位。

要求返回每一个滑动窗口内的中位数,解释中位数定义,例如:对于[2,3,4],中位数是3;对于[2,3],中位数是 (2 + 3) / 2 = 2.5

注意:为了简化窗口计算,规定如果没有累计到窗口大小的数,不能触发计算,即不输出结果!


输入描述:
输入两个数字n,k。n表示数组长度,k表示窗口大小
加下来n个整数用空格隔开,表示nums数组
(1<=k<=n)
(1<=n<=1000)


输出描述:
输出若干个数字,表示滑窗依次移动得到的结果,保留小数点后一位数字
示例1

输入

8 3
1 3 -1 -3 5 3 6 7

输出

1.0 -1.0 -1.0 3.0 5.0 6.0

说明

callist = input('')
nums = input('')
callist = callist.split(' ')
n = int(callist[0])    #数组长度
k = int(callist[1])    #窗口大小
nums = nums.split(' ')
resultlist = []

for i in range(len(nums)):
    nums[i]=float(nums[i])
for j in range(0,len(nums)-k+1):
    slide=nums[j:j+k]
    slide.sort()
    if(k%2==0):
        median = (slide[int(k/2)-1]+slide[int(k/2)+1-1])/2
    else:
        median = (slide[int((k+1)/2)-1])
    median = str(median)
    resultlist.append(median)
resultstring = ' '.join(resultlist)
print(resultstring)

编辑于 2020-03-17 12:38:38 回复(1)
直接调用statistic中的median函数求取中位数
import statistics

n, k = map(int, input().split())
data = list(map(int, input().split()))
for i in range(n - k + 1):
     print('%.1f ' % statistics.median(data[i: i + k]), end='')


发表于 2020-12-23 15:30:37 回复(0)
import statistics
n, k = input().split()
nums = list(map(int,input().split()))
result = ""
if int(n) >= int(k):
    for idx, val in enumerate(nums[0:int(n)-int(k)+1]):
        result = result + str(round(float(statistics.median(nums[idx:idx+int(k)])),2)) + " "
print(result)


发表于 2020-03-29 11:01:58 回复(1)

用python可以使用statistic模块快速求中位数,如果使用其他语言,可以考虑使用快排的partition来求中位数

使用statistic模块:

import sys
import statistics

def parse_nums(nums_str):
    return [int(x) for x in nums_str.strip().split()]

for line in sys.stdin:
    n, k = parse_nums(line)
    nums = parse_nums(input())
    res = []
    for i in range(n - k + 1):
        res.append(statistics.median(nums[i:i + k]))
    print(' '.join(['%.1f' % x for x in res]))

自己实现快速求解中位数:

import sys
import random


def parse_nums(nums_str):
    return [int(x) for x in nums_str.strip().split()]


def partition(arr, low, high):
    r = random.randint(low, high)
    arr[low], arr[r] = arr[r], arr[low]
    pivot = arr[low]
    while low < high:
        while low < high and arr[high] >= pivot:
            high -= 1
        arr[low] = arr[high]
        while low < high and arr[low] <= pivot:
            low += 1
        arr[high] = arr[low]
    arr[low] = pivot
    return low


def get_kth(nums, k):
    mid = partition(nums, 0, len(nums) - 1)
    if mid == k:
        return nums[mid]
    elif mid < k:
        return get_kth(nums[mid + 1:], k - mid - 1)
    else:
        return get_kth(nums[:mid], k)


def get_medium(nums):
    if len(nums) % 2 == 1:
        return get_kth(nums, len(nums) // 2)
    else:
        a = get_kth(nums, len(nums) // 2)
        b = get_kth(nums, len(nums) // 2 - 1)
        return (a + b) / 2


for line in sys.stdin:
    n, k = parse_nums(line)
    nums = parse_nums(input())
    res = []
    for i in range(n - k + 1):
        res.append(get_medium(nums[i:i + k]))
    print(' '.join(['%.1f' % x for x in res]))
发表于 2020-04-05 13:33:00 回复(1)
[n,k] = input().strip().split()
nums = input().strip().split()
nums = list(map(int,nums))
n = int(n)
k = int(k)
ans = []
def Median(input_list):
    input_list.sort()
    n = len(input_list)
    if n%2 == 1:
        median_value= format(input_list[int((n+1)/2)-1], '.1f')
    else:
        median_value= format((input_list[int(n/2)-1] + input_list[int(n/2)])/2, '.1f')
    return median_value

if k%2 == 1:
    for i in range(n-k+1):
        res = []
        for j in range(k):
            res.append(nums[i + j])
        median_value = Median(res)
        ans.append(median_value)
else:
    for i in range(n-k+1):
        res = []
        for j in range(k):
            res.append(nums[i+j])
        median_value = Median(res)
        ans.append(median_value)
ans = ' '.join(ans)
print(ans)
菜比代码
发表于 2023-06-08 10:14:09 回复(0)
import statistics
n, k = [int(x) for x in input().split(" ")]
array = [int(x) for x in input().split(" ")]
print(*[round(float(statistics.median(array[i:i+k])),1) for i in range(n-k+1)])

发表于 2023-03-19 13:53:36 回复(0)
看了别人的再看自己的 真是无语了
a=[int(x) for x in input().split()]
b=[int(x) for x in input().split()]
pri=[]
# print(a,b)
for i in range(0,a[0]-a[1]+1):
    s=list()
    s=b[i:i+a[1]]
    s.sort()
    if a[1]%2==0:
        mid=(s[a[1]//2-1]+s[a[1]//2])/2
    else:
        mid=s[(a[1]//2)]       
    pri.append(mid*1.0)
for i in pri:
    print(i,end=' ')
发表于 2022-09-16 10:43:07 回复(0)
a,b = [int(i) for i in input().split()]
lst = [int(i) for i in input().split()]

# 求中位数
def get_median(use):
    use.sort()  # 中位数是一个排序好的数组的中间数
    if len(use) % 2 == 1:
        start = len(use) // 2
        end = start + 1
        ans = float(use[start:end][0])
    else:
        start = len(use) // 2
        end = start + 1
        use_1 = use[start-1:end]
        ans = round(float(sum(use_1)/2), 2)
    return ans

result = ''
for i in range(a-(b-1)):
    use = lst[i:i+b]
    ans = get_median(use)
    result += str(ans) + ' '
print(result)
发表于 2021-03-22 10:14:13 回复(0)
def median(n,k,nums):
    
        for i in range(n-k+1):
            a=nums[i:i+k].copy()
            a.sort()
            j=k//2
            if k%2==1:
                print('%.1f'%a[j],end=' ')
            else:
                print('%.1f'%((a[j-1]+a[j])/2),end=' ')        

if __name__=='__main__':
    n,k = map(int,input().split(' '))
    nums = list(map(int,input().split(' ')))
    median(n,k,nums)

发表于 2021-02-21 10:51:19 回复(0)
n,k = map(int,input().split())
number = list(map(int,input().split()))
result = []

if k % 2 == 1:
    for i in range(len(number)):
        if (i+k) <= len(number):
            temp = number[i:i+k]
            temp.sort()
            result.append(temp[(int((k+1)/2)) - 1])
            
if k % 2 == 0:
    for i in range(len(number)):
        if (i+k) <= len(number):
            temp = number[i:i+k]
            temp.sort()
            a = int(k/2)
            result.append((temp[a-1]+temp[a])/2)
            
print(' '.join(['%.1f' % x for x in result]))
发表于 2020-11-20 17:52:58 回复(0)
n,d=map(int,input().split(' '))
list=list(map(int,input().split(' ')))

def F(n,d,list):
    temp=[]
    if n>=d and n>=1:
        for i in range(n-d+1):
            list1=sorted(list[i:i+d])
            if d%2!=0:
                mid=len(list1)//2
                temp.append(list1[mid])
            else:
                mid=len(list1)//2
                temp.append((list1[mid]+list1[mid-1])/2)
        return temp
print(' '.join(['%.1f'%x for x in F(n, d, list)]))
发表于 2020-11-15 18:07:05 回复(0)
A = input().strip().split()
n = int(A[0])
k = int(A[1])
data = input().strip().split()
s = [float(i) for i in data]
res = []
mid = k // 2
for i in range(len(s)-k+1):
    cur = sorted(s[i:i+k])
    if k % 2 != 0:
        res.append(round(cur[mid],2))
    else:
        res.append(round( (cur[mid] + cur[mid-1]) / 2,2))
res = [str(i) for i in res]
print(' '.join(res))

发表于 2020-08-21 22:50:50 回复(1)
为什么用numpy库np.median()求中值不行啊,而statistics库就可以?
import statistics
l1=list(map(int,input().split()))
l2=list(map(int,input().split()))
n=l1[0]
m=l1[1]
l=[]
for i in range(n-m+1):
    l3=l2[i:i+m]
    s=statistics.median(l3)
    print('%.1f'%s,end=' ')



发表于 2020-08-20 16:44:28 回复(0)
import numpy as np
nm = input('请输入两个数:')#中间用空格隔开
nums = input('请输入数组:')
n_m= nm.split(' ') #用空格分隔数组的长度和切割框的长度
nums_ = nums.split(' ')
n = int(n_m[0])
m = int(n_m[1])
for i in range(n-m+1):#控制切割框位移次数
    split_list = list()
    for j in range(i,m+i):#控制添加元素个数
        split_list.append(int(nums_[j]))#列表末尾添加元素
    x = np.array([split_list])#列表转numpy数组
    print(int(np.median(x)))#求中位数

发表于 2020-07-17 15:37:28 回复(0)
import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int n, k;
        int[] nums=new int[1005];
        PriorityQueue<Integer> max = new PriorityQueue<>();
        PriorityQueue<Integer> min = new PriorityQueue<>(Comparator.<Integer>reverseOrder());
        n=scanner.nextInt();
        k=scanner.nextInt();
        for (int i = 0; i < n; i++) {
            nums[i]=scanner.nextInt();
        }
        for(int i=0;i<n;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());
            }
            if (i >= k - 1) {
                if(k%2==0){
                    System.out.print((min.peek()+max.peek())/2.0);
                }else {
                    System.out.print(min.peek()/1.0);
                }
 
                if(i!=n-1){
                    System.out.print(" ");
                }
            }
        }
    }
}

发表于 2020-03-12 02:59:38 回复(0)