[Leetcode] 480. Sliding Window Median 解题报告
来源:互联网 发布:护肤品行业数据 编辑:程序博客网 时间:2024/05/18 19:40
题目:
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Examples:[2,3,4]
, the median is 3
[2,3]
, the median is (2 + 3) / 2 = 2.5
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Your job is to output the median array for each window in the original array.
For example,
Given nums = [1,3,-1,-3,5,3,6,7]
, and k = 3.
Window position Median--------------- -----[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
Therefore, return the median sliding window as [1,-1,-1,3,5,6]
.
Note:
You may assume k
is always valid, ie: k
is always smaller than input array's size for non-empty array.
思路:
1、用两个multiset:我自己开始写了一个实现,思路是用两个multiset,其中一个保存移动窗口中一半小的数,另一个保存移动窗口中一半大的数。在窗口移动的过程中,可以用logk的时间对两个multiset进行调整,并且可以在O(1)的时间内获得当前移动窗口中的中位数。因此,整个代码的时间复杂度仍然是O(nlogk),空间复杂度是O(k)。
2、用一个multiset:后来看了网上的代码,只用了一个multiset。它的思路是在窗口移动的过程中,保持对指向中位数的迭代器的更新。这样代码就简洁很多了。当然时间复杂度仍然是O(nlogk)。
不得不承认,这就是菜鸟和高手的差距。
代码:
1、用两个multiset:
class Solution {public: vector<double> medianSlidingWindow(vector<int>& nums, int k) { multiset<int> smaller, larger; vector<double> ans; for (int i = 0; i < nums.size(); ++i) { if (i >= k) { removeNum(smaller, larger, nums[i - k]); } addNum(smaller, larger, nums[i]); if (i + 1 >= k) { if (k % 2 != 0) { ans.push_back(*smaller.rbegin()); } else { double v1 = static_cast<double>(*smaller.rbegin()); double v2 = static_cast<double>(*larger.begin()); ans.push_back((v1 + v2) / 2); } } } return ans; }private: void addNum(multiset<int> &smaller, multiset<int> &larger, int num) { if (smaller.size() == larger.size()) { // add to smaller smaller.insert(num); } else { // add to larger larger.insert(num); } if (!smaller.empty() && !larger.empty() && *smaller.rbegin() > *larger.begin()) { int small = *smaller.rbegin(), large = *larger.begin(); smaller.erase(--smaller.end()); larger.erase(larger.begin()); smaller.insert(large), larger.insert(small); } } void removeNum(multiset<int> &smaller, multiset<int> &larger, int num) { if (!smaller.empty() && num <= *smaller.rbegin()) { // remove from smaller auto it = smaller.find(num); if (it != smaller.end()) { smaller.erase(it); } } else if (!larger.empty()) { // remove from larger auto it = larger.find(num); if (it != larger.end()) { larger.erase(it); } } if (smaller.size() < larger.size()) { int value = *larger.begin(); larger.erase(larger.begin()); smaller.insert(value); } }};
2、用一个multiset:
class Solution {public: vector<double> medianSlidingWindow(vector<int>& nums, int k) { multiset<int> window(nums.begin(), nums.begin() + k); auto mid = next(window.begin(), k / 2); vector<double> medians; for (int i = k; ; i++) { medians.push_back((double(*mid) + *prev(mid, 1 - k % 2)) / 2); // Push the current median if (i == nums.size()) { // If all done, return return medians; } window.insert(nums[i]); // Insert nums[i] if (nums[i] < *mid) { --mid; } if (nums[i - k] <= *mid) { // Erase nums[i-k]. ++mid; } window.erase(window.lower_bound(nums[i-k])); } return medians; }};
- [Leetcode] 480. Sliding Window Median 解题报告
- Leetcode 480. Sliding Window Median 滑动窗口中的中位数 解题报告
- LeetCode 480. Sliding Window Median
- [LeetCode]480. Sliding Window Median
- [leetcode]480. Sliding Window Median
- leetcode 480. Sliding Window Median
- [LeetCode] Sliding Window Median
- [leetcode] 239. Sliding Window Maximum 解题报告
- [Leetcode] 239. Sliding Window Maximum 解题报告
- 480. Sliding Window Median
- 480. Sliding Window Median
- 480. Sliding Window Median
- leetcode-480-Sliding Window Median
- leetcode 480. Sliding Window Median 滑动窗口中位数
- [LeetCode] Sliding Window Median 滑动窗口中位数
- Lintcode 360 Sliding Window Median
- LintCode:H-Sliding Window Median
- leetcode Sliding Window Maximum
- 2017最新版省市区三级联动下拉框+所有源代码以及数据库
- Android TensorFlow 智能语音识别
- 自定义View点击计算次数的demo
- Oracle实现行列转换的方法分析
- 阿里大数据分析展示工具DataV
- [Leetcode] 480. Sliding Window Median 解题报告
- 计算不规则多边形的面积、中心、重心(计算地图围栏中心点)
- JDBC连接多个库进行数据操作(常用于数据迁移)
- 图数据库Neo4j安装及入门:
- 正则表达式汇总表
- Docker和虚拟机的区别
- 手把手带你走进MVP +Dagger2 + DataBinding+ Rxjava+Retrofit 的世界
- String,StringBuffer,StringBuilder三者之间的区别
- 无法通过ip访问redis服务