【算法练习】lc每日一题 双堆和multiset/480.滑动窗口中位数

目录

 

480. 滑动窗口中位数

方法一  利用multiset

思路

代码

方法二  大顶堆小顶堆 维护平衡

思路

代码


480. 滑动窗口中位数

题目链接:https://leetcode-cn.com/problems/sliding-window-median/

 

难度困难239

中位数是有序序列最中间的那个数。如果序列的长度是偶数,则没有最中间的数;此时中位数是最中间的两个数的平均数。

例如:

  • [2,3,4],中位数是 3
  • [2,3],中位数是 (2 + 3) / 2 = 2.5

给你一个数组 nums,有一个长度为 k 的窗口从最左端滑动到最右端。窗口中有 k 个数,每次窗口向右移动 1 位。你的任务是找出每次窗口移动后得到的新窗口中元素的中位数,并输出由它们组成的数组。

 

示例:

给出 nums = [1,3,-1,-3,5,3,6,7],以及 k = 3。

窗口位置                      中位数
---------------               -----
[1  3  -1] -3  5  3  6  7       1
 1 [3  -1  -3] 5  3  6  7      -1
 1  3 [-1  -3  5] 3  6  7      -1
 1  3  -1 [-3  5  3] 6  7       3
 1  3  -1  -3 [5  3  6] 7       5
 1  3  -1  -3  5 [3  6  7]      6

 因此,返回该滑动窗口的中位数数组 [1,-1,-1,3,5,6]

 

提示:

  • 你可以假设 k 始终有效,即:k 始终小于输入的非空数组的元素个数。
  • 与真实值误差在 10 ^ -5 以内的答案将被视作正确答案。

方法一  利用multiset

思路

这道题我的思路是平常的思路,就是会超时的思路,然后看别人的题解,非常有启发的一点是,在做题的过程中一定要记住要维护什么,比如这个题就要维护一个有序的k个数,然后窗口滑动要插入、删除相应的数,然后呢如果每次滑动窗口都排序的话时间复杂度是O(klogk),然后大概的总时间复杂度应该是O(N(klogk)) ?

为了减少时间复杂度,利用已经实现的数据结构 ,看别人的题解:

中位数 是有序序列最中间的那个数。也就是说我们必须对窗口内的元素「排序」。我们知道排序的时间复杂度一般是 O(k * log(k)) ,还是比较高的。这个题如果对每个区间都进行分别排序肯定会超时,否则也不会是个 Hard 题目。

怎么快速求中位数呢&#x

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是用set维护位数的C程序: ```c #include <stdio.h> #include <stdlib.h> #include <set> using namespace std; int main() { multiset<int> nums; // 定义multiset容器 int n, x; scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &x); nums.insert(x); // 插入元素 if(i % 2 == 1) { // 奇数个元素时,取间值 multiset<int>::iterator it = nums.begin(); // 获取迭代器 advance(it, i / 2); // 移动迭代器i/2个位置 printf("%d\n", *it); // 输出位数 } else { // 偶数个元素时,取间两个数的平均值 multiset<int>::iterator it1 = nums.begin(); // 获取迭代器 advance(it1, i / 2 - 1); // 移动迭代器 multiset<int>::iterator it2 = it1; it2++; // 移动迭代器 printf("%d\n", (*it1 + *it2) / 2); // 输出位数 } } return 0; } ``` 程序的流程是这样的: 1. 定义一个multiset容器,用于存储输入的数。 2. 读入输入的数,将数插入multiset。 3. 根据当前元素个数,计算位数并输出。 对于奇数个元素的情况,直接找到间位置的数即可。由于multiset元素已经按从小到大的顺序排序,因此可以直接使用begin()函数获取第一个元素的迭代器,然后使用advance()函数移动迭代器i/2个位置即可得到位数。 对于偶数个元素的情况,需要找到间两个数的平均值。同样地,可以先找到第i/2-1个数和第i/2个数的迭代器,然后将它们的值相加,再除以2即可得到位数。 最后,输出位数即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值