C++ 中的滑動視窗中位數
假設我們有一列數字,並且有一個視窗大小 k,我們需要使用滑動視窗的方式找到中位數列表。因此,如果分佈如下所示:
視窗位置 | 中位數 | ||||||||
---|---|---|---|---|---|---|---|---|---|
1 | 3 | -1 | -3 | 5 | 3 | 6 | 8 | 1 | |
1 | 3 | -1 | -3 | 5 | 3 | 6 | 8 | -1 | |
1 | 3 | -1 | -3 | 5 | 3 | 6 | 8 | -1 | |
1 | 3 | -1 | -3 | 5 | 3 | 6 | 8 | 3 | |
1 | 3 | -1 | -3 | 5 | 3 | 6 | 8 | 5 | |
1 | 3 | -1 | -3 | 5 | 3 | 6 | 8 | 6 |
這裡我們假設 k 為 3,結果將是 [1,-1,-1,3,5,6]
為了解決這個問題,我們將遵循以下步驟:
- 定義一個集合 arr
- 定義一個函式 insert(),它將接收 x,
- 將 x 插入到 arr 中
- 定義一個函式 delete_(),它將接收 x,
- 從 arr 中刪除 x,如果存在
- 定義一個函式 getMedian()
- n := arr 的大小
- a := 從 arr 的第一個元素開始向前跳躍 n/2 – 1 步,並獲取其值
- b := 從 arr 的第一個元素開始向前跳躍 n/2 步,並獲取其值
- 如果 arr 的大小為,則:
- 返回 b
- 返回 (a + b) * 0.5
- 從主方法執行以下操作
- 定義一個數組 ans
- 清空陣列 arr
- 初始化 i := 0,當 i < k 時,更新(i 增加 1),執行:
- 呼叫函式 insert(nums[i])
- 初始化 i := k,j := 0,當 i < nums 的大小,更新(i 增加 1),(j 增加 1),執行:
- 將 getMedian() 的返回值插入到 ans 的末尾
- 呼叫函式 delete_(nums[j])
- 呼叫函式 insert(nums[i])
- 將 getMedian() 的返回值插入到 ans 的末尾
- 返回 ans
讓我們看看下面的實現來更好地理解:
示例
#include <bits/stdc++.h> using namespace std; void print_vector(vector<auto> v){ cout << "["; for(int i = 0; i<v.size(); i++){ cout << v[i] << ", "; } cout << "]"<<endl; } class Solution { public: multiset <double> arr; void insert(double x){ arr.insert(x); } void delete_(double x){ arr.erase(arr.find(x)); } double getMedian(){ int n = arr.size(); double a = *next(arr.begin(), n / 2 - 1); double b = *next(arr.begin(), n / 2); if(arr.size() & 1)return b; return (a + b) * 0.5; } vector<double> medianSlidingWindow(vector<int>& nums, int k) { vector <double> ans; arr.clear(); for(int i = 0; i < k; i++){ insert(nums[i]); } for(int i = k, j = 0; i < nums.size(); i++, j++){ ans.push_back(getMedian()); delete_(nums[j]); insert(nums[i]); } ans.push_back(getMedian()); return ans; } }; main(){ Solution ob; vector<int> v = {1,3,-1,-3,5,3,6,8}; print_vector(ob.medianSlidingWindow(v, 3)); }
輸入
{1,3,-1,-3,5,3,6,8}
輸出
[1, -1, -1, 3, 5, 6, ]
廣告