本文概述
- CPP
给定一个整数arr[]和整数K的数组,任务是找到每个大小为K的窗口的中值,从左开始,每次向右移动一个位置。
例子:
输入:arr[] = {-1, 5, 13, 8, 2, 3, 3, 1}, K = 3简单的方法:
输出:5 8 8 3 3 3
说明:
第一个窗口:{-1, 5, 13}中值= 5
第二窗口:{5, 13, 8}中位数= 8
第三窗口:{13, 8, 2}中位数= 8
第四窗口:{8, 2, 3}中位数= 3
第五窗口:{2, 3, 3 }中位数= 3
第六个窗口:{3, 3, 1}中位数= 3
输入:arr[] = {-1、5、13、8、2、3、3、1}, K = 4
输出:6.5 6.5 5.5 3.0 2.5
解决这个问题最简单的方法是遍历每个大小为K的窗口,对窗口的元素进行排序,并找到中间的元素。打印每个窗口的中间元素作为中间值。
【算法设计(数组中滑动窗口的中位数|S2)】时间复杂度:O(N * KlogK)
辅助空间:O(K)
排序集方法:参考数组中滑动窗口的中位数解决问题SortedSet.
有序集方法:
在本文中,一种使用基于策略的有序集数据结构来解决这个问题的方法。
请按照以下步骤解决问题:
- 插入第一个窗口大小?在Ordered_set中(维护排序顺序)。因此, 此有序集合的中间元素是相应窗口的所需中间值。
- 中间元素可以通过以下方法中的find_by_order()方法获得:O(logN)计算复杂度。
- 通过删除上一个窗口的第一个元素并插入新元素, 进入以下窗口。要从集合中删除任何元素, 请在Ordered_Set使用order_by_key(), 以O(logN)的计算复杂度获取结果, 并且擦除()通过使用以下命令在Ordered_Set中搜索其获得的顺序来查找该元素find_by_order()方法。现在, 为新窗口添加新元素。
- 对每个窗口重复上述步骤, 并打印相应的中位数。
CPP
//C++ Program to implement the
//above approach
#include <
bits/stdc++.h>
#include <
ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
//Policy based data structure
typedef tree<
int , null_type, less_equal<
int>
, rb_tree_tag, tree_order_statistics_node_update>
Ordered_set;
//Function to find and return the
//median of every window of size k
void findMedian( int arr[], int n, int k)
{Ordered_set s;
for ( int i = 0;
i <
k;
i++)
s.insert(arr[i]);
if (k &
1) {//Value at index k/2
//in sorted list.
int ans = *s.find_by_order(k /2);
cout <
<
ans <
<
" " ;
for ( int i = 0;
i <
n - k;
i++) {//Erasing Element out of window.
s.erase(s.find_by_order(
s.order_of_key(
arr[i])));
//Inserting newer element
//to the window
s.insert(arr[i + k]);
//Value at index k/2 in
//sorted list.
ans = *s.find_by_order(k /2);
cout <
<
ans <
<
" " ;
}
cout <
<
endl;
}
else {//Getting the two middle
//median of sorted list.
float ans = (( float )*s.find_by_order(
(k + 1) /2 - 1)
+ ( float )*s.find_by_order(k
/2))
/2;
printf ( "%.2f " , ans);
for ( int i = 0;
i <
n - k;
i++) {
s.erase(s.find_by_order(
s.order_of_key(arr[i])));
s.insert(arr[i + k]);
ans = (( float )*s.find_by_order(
(k + 1) /2 - 1)
+ ( float )*s.find_by_order(k
/2))
/2;
printf ( "%.2f " , ans);
}
cout <
<
endl;
}
}//Driver Code
int main()
{
int arr[] = { -1, 5, 13, 8, 2, 3, 3, 1 };
int k = 3;
int n = sizeof (arr)
/sizeof (arr[0]);
findMedian(arr, n, k);
return 0;
}
输出如下:
5 8 8 3 3 3
时间复杂度:O(NlogK)
辅助空间:O(K)
推荐阅读
- 快速排序与合并排序有什么区别()
- 免费win7旗舰版安装图文详细教程
- 电脑公司Win8纯净系统64位下载
- windows7 32位系统重装图文详细教程
- 番茄花园萝卜家园系统通用安装办法
- 深度技术欢度国庆纯净版xp系统下载
- ghost过程中出错原因及处理办法
- 安装win10 win8.1双系统图文详细教程
- 重装镜像win7系统图解图文详细教程