LeetCode-480. 滑動(dòng)窗口中位數(shù)

題目描述 滑動(dòng)窗口中位數(shù)

中位數(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 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
因此,返回該滑動(dòng)窗口的中位數(shù)數(shù)組 [1,-1,-1,3,5,6]。

提示:
假設(shè)k是合法的,即:k 始終小于輸入的非空數(shù)組的元素個(gè)數(shù).

解題思路

維護(hù)一個(gè)k維的有序數(shù)組,每次逐個(gè)插入新元素,并刪除舊元素。

代碼

class Solution {
public:
    void insertNum(vector<int>& data, int num){
        if(data.empty()) data.push_back(num);
        else{
            int i=data.size()-1;
            int j=i;
            while(i>0){
                if(num < data[i]) j--;
                i--;
            }
            if(num > data[i]) data.insert(data.begin()+j+1, num);
            else data.insert(data.begin()+j , num);
        }
    }

    void deleteNum(vector<int>& data, int num){
        int left = 0;
        int right = data.size()-1;

        while(left<=right){
            int mid = (left+right)/2;
            if(data[mid]==num){
                data.erase(data.begin() + mid);
                break;
            }else if(data[mid]<num) left = mid + 1;
            else if(data[mid]>num)right = mid - 1;
        }
    }

    double getMedium(vector<int>& data, int k){
        if(k%2!=0)
            return data[k/2];
        else
            return ((double)data[k/2] + (double)data[k/2-1])/2.0;
    }

    vector<double> medianSlidingWindow(vector<int>& nums, int k) {
        vector<double> res;
        vector<int> data;
        for(int i=0; i < nums.size();){
//            cout << "before:";
//            for(auto num:data) cout << num << " ";
//            cout << endl;
            if(data.empty()){
                while(data.size()<k){
                    insertNum(data, nums[i]);
                    i++;
                }
            }else{
                insertNum(data, nums[i]);
                i++;
            }
//            cout << "after:";
//            for(auto num:data) cout << num << " ";
//            cout << endl;
            res.push_back(getMedium(data, k));
            deleteNum(data, nums[i-k]);
        }
        return res;
    }
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 2. 實(shí)現(xiàn) Singleton 3. 數(shù)組中重復(fù)的數(shù)字 4. 二維數(shù)組中的查找 5. 替換空格 6. 從尾到...
    Observer_____閱讀 3,159評(píng)論 0 1
  • 給定一個(gè)包含 n 個(gè)整數(shù)的數(shù)組,和一個(gè)大小為 k 的滑動(dòng)窗口,從左到右在數(shù)組中滑動(dòng)這個(gè)窗口,找到數(shù)組中每個(gè)窗口內(nèi)的...
    soSweety閱讀 1,235評(píng)論 0 0
  • 本文是我自己在秋招復(fù)習(xí)時(shí)的讀書筆記,整理的知識(shí)點(diǎn),也是為了防止忘記,尊重勞動(dòng)成果,轉(zhuǎn)載注明出處哦!如果你也喜歡,那...
    波波波先森閱讀 4,361評(píng)論 0 23
  • 在C語言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 4,035評(píng)論 0 2
  • 文/汝之尾巴草 上半年的時(shí)候流行一句話:“睡你媽逼,起來嗨”而我現(xiàn)在只想對(duì)你說一句:“嗨你媽逼,快去睡”! /01...
    汝之尾巴草閱讀 1,363評(píng)論 73 39

友情鏈接更多精彩內(nèi)容