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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

1. 題目

中位數(shù)是有序序列最中間的那個(gè)數(shù)。
如果序列的大小是偶數(shù),則沒有最中間的數(shù);此時(shí)中位數(shù)是最中間的兩個(gè)數(shù)的平均數(shù)。

例如:
[2,3,4],中位數(shù)是 3
[2,3],中位數(shù)是 (2 + 3) / 2 = 2.5
給你一個(gè)數(shù)組 nums,有一個(gè)大小為 k 的窗口從最左端滑動(dòng)到最右端。
窗口中有 k 個(gè)數(shù),每次窗口向右移動(dòng) 1 位。
你的任務(wù)是找出每次窗口移動(dòng)后得到的新窗口中元素的中位數(shù),并輸出由它們組成的數(shù)組。

示例: 給出 nums = [1,3,-1,-3,5,3,6,7],以及 k = 3。窗口位置 中位數(shù) --------------- ----- [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因此,返回該滑動(dòng)窗口的中位數(shù)數(shù)組 [1,-1,-1,3,5,6]。提示: 你可以假設(shè) k 始終有效,即:k 始終小于輸入的非空數(shù)組的元素個(gè)數(shù)。 與真實(shí)值誤差在 10 ^ -5 以內(nèi)的答案將被視作正確答案。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/sliding-window-median
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

2. 解題

類似題目:
LeetCode 295. 數(shù)據(jù)流的中位數(shù)(大小堆)
LeetCode 703. 數(shù)據(jù)流中的第K大元素(優(yōu)先隊(duì)列)

參考我的博客 數(shù)據(jù)結(jié)構(gòu) 堆(優(yōu)先隊(duì)列)
參考大小堆的思想,一個(gè)堆最多比另一個(gè)堆最多多一個(gè)元素,不再多講,請參考上面鏈接

  • 關(guān)鍵要實(shí)現(xiàn)從堆中刪除窗口左端點(diǎn),那么用 set 來當(dāng)做堆就可以突破優(yōu)先隊(duì)列(堆)不能刪除非堆頂元素
  • 本題:小堆size = 大堆size or 小堆size = 大堆size+1
  • k 為 奇數(shù),直接返回小堆頂 set.begin()
  • k 為 偶數(shù),返回兩個(gè)堆頂?shù)钠骄?/li>
class Solution { // C++multiset<int> minheap;//begin 是小的元素multiset<int,greater<int>> maxheap;//begin 是大的元素 public:vector<double> medianSlidingWindow(vector<int>& nums, int k) {// k = 1,直接返回?cái)?shù)組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個(gè)a = (*maxheap.begin()), b = (*minheap.begin());ans[idx++] = (k&1) ? b : (a+b)/2.0;//記錄中位數(shù)for(i = 0 ; j < n; ++i,++j){maxheap_minheap_del(nums[i]);//刪除左端點(diǎn)maxheap_minheap_add(nums[j]);//加入右端點(diǎn)a = (*maxheap.begin()), b = (*minheap.begin());ans[idx++] = (k&1) ? b : (a+b)/2.0;//記錄中位數(shù)}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

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。