日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 480. 滑动窗口中位数(大小堆升级版+set实现)

發布時間:2024/7/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 480. 滑动窗口中位数(大小堆升级版+set实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 題目

中位數是有序序列最中間的那個數。
如果序列的大小是偶數,則沒有最中間的數;此時中位數是最中間的兩個數的平均數。

例如:
[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 11 [3 -1 -3] 5 3 6 7 -11 3 [-1 -3 5] 3 6 7 -11 3 -1 [-3 5 3] 6 7 31 3 -1 -3 [5 3 6] 7 51 3 -1 -3 5 [3 6 7] 6因此,返回該滑動窗口的中位數數組 [1,-1,-1,3,5,6]。提示: 你可以假設 k 始終有效,即:k 始終小于輸入的非空數組的元素個數。 與真實值誤差在 10 ^ -5 以內的答案將被視作正確答案。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/sliding-window-median
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。

2. 解題

類似題目:
LeetCode 295. 數據流的中位數(大小堆)
LeetCode 703. 數據流中的第K大元素(優先隊列)

參考我的博客 數據結構 堆(優先隊列)
參考大小堆的思想,一個堆最多比另一個堆最多多一個元素,不再多講,請參考上面鏈接

  • 關鍵要實現從堆中刪除窗口左端點,那么用 set 來當做堆就可以突破優先隊列(堆)不能刪除非堆頂元素
  • 本題:小堆size = 大堆size or 小堆size = 大堆size+1
  • k 為 奇數,直接返回小堆頂 set.begin()
  • k 為 偶數,返回兩個堆頂的平均值
class Solution { // C++multiset<int> minheap;//begin 是小的元素multiset<int,greater<int>> maxheap;//begin 是大的元素 public:vector<double> medianSlidingWindow(vector<int>& nums, int k) {// k = 1,直接返回數組if(k == 1) return vector<double>(nums.begin(), nums.end());int n = nums.size(), i = 0, j = 0, idx = 0;long a, b;//避免溢出 longvector<double> ans(n-k+1);for( ; j < k; ++j)maxheap_minheap_add(nums[j]);//先加入k個a = (*maxheap.begin()), b = (*minheap.begin());ans[idx++] = (k&1) ? b : (a+b)/2.0;//記錄中位數for(i = 0 ; j < n; ++i,++j){maxheap_minheap_del(nums[i]);//刪除左端點maxheap_minheap_add(nums[j]);//加入右端點a = (*maxheap.begin()), b = (*minheap.begin());ans[idx++] = (k&1) ? b : (a+b)/2.0;//記錄中位數}return ans;}void maxheap_minheap_add(int x){if(minheap.empty())minheap.insert(x);else if(maxheap.size() == minheap.size()){if(x >= *maxheap.begin())minheap.insert(x);else{minheap.insert(*maxheap.begin());maxheap.erase(maxheap.begin());maxheap.insert(x);}}else if(maxheap.size() < minheap.size()){if(x <= *minheap.begin())maxheap.insert(x);else{maxheap.insert(*minheap.begin());minheap.erase(minheap.begin());minheap.insert(x);}}}void maxheap_minheap_del(int x){if(maxheap.size() < minheap.size()){auto it = minheap.find(x);if(it != minheap.end())minheap.erase(it);else{maxheap.erase(maxheap.find(x));maxheap.insert(*minheap.begin());minheap.erase(minheap.begin());}}else if(maxheap.size() == minheap.size()){auto it = maxheap.find(x);if(it != maxheap.end())maxheap.erase(it);else{minheap.erase(minheap.find(x));minheap.insert(*maxheap.begin());maxheap.erase(maxheap.begin());}}} };

108 ms 18.9 MB

總結

以上是生活随笔為你收集整理的LeetCode 480. 滑动窗口中位数(大小堆升级版+set实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。