<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ?LeetCode刷題實戰(zhàn)295:數(shù)據(jù)流的中位數(shù)

          共 5788字,需瀏覽 12分鐘

           ·

          2021-06-17 20:50

          算法的重要性,我就不多說了吧,想去大廠,就必須要經(jīng)過基礎(chǔ)知識和業(yè)務(wù)邏輯面試+算法面試。所以,為了提高大家的算法能力,這個公眾號后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !

          今天和大家聊的問題叫做 數(shù)據(jù)流的中位數(shù),我們先來看題面:
          https://leetcode-cn.com/problems/find-median-from-data-stream/


          中位數(shù)是有序列表中間的數(shù)。如果列表長度是偶數(shù),中位數(shù)則是中間兩個數(shù)的平均值。
          例如,
          [2,3,4] 的中位數(shù)是 3
          [2,3] 的中位數(shù)是 (2 + 3) / 2 = 2.5
          設(shè)計一個支持以下兩種操作的數(shù)據(jù)結(jié)構(gòu):
          • void addNum(int num) - 從數(shù)據(jù)流中添加一個整數(shù)到數(shù)據(jù)結(jié)構(gòu)中。

          • double findMedian() - 返回目前所有元素的中位數(shù)。


          示例


          addNum(1)
          addNum(2)
          findMedian() -> 1.5
          addNum(3)
          findMedian() -> 2

          進階:

          如果數(shù)據(jù)流中所有整數(shù)都在 0 到 100 范圍內(nèi),你將如何優(yōu)化你的算法?
          如果數(shù)據(jù)流中 99% 的整數(shù)都在 0 到 100 范圍內(nèi),你將如何優(yōu)化你的算法?

          解題

          https://www.cnblogs.com/paulprayer/p/9884332.html


          堆是一個非常重要的數(shù)據(jù)結(jié)構(gòu),LeetCode網(wǎng)站把這一道劃分在“堆”一類中,也是提醒我們使用堆結(jié)構(gòu)。這道題很巧妙,我是聽了算法課(??途W(wǎng)的左程云大牛)的講解才弄明白。這里的代碼是自己聽懂了思路,獨立寫出來的。

          關(guān)鍵思路:建立兩個堆(使用priority_queue實現(xiàn)),一個大根堆,一個小根堆。

          一個大根堆,保存所有整數(shù)中較小的1/2;一個小根堆,保存所有整數(shù)中較大的1/2;
          并且,依次添加元素過程中,兩個堆元素個數(shù)的差的絕對值不能超過1;這樣,兩個堆建立好了以后,

          如果輸入的元素個數(shù) n 是偶數(shù),則兩個堆的元素個數(shù)相等,分別取大根堆的頂和小根堆的頂,取平均值,即是所求的整個數(shù)據(jù)流的中位數(shù);

          如果輸入的元素個數(shù) n 是奇數(shù),則必有一個堆的元素個數(shù)為(n/2+1),返回這個堆的頂,即為所求的中位數(shù)。

          class MedianFinder {
          public:
              /** initialize your data structure here. */
              MedianFinder() {
                  
              }
              
              void addNum(int num) {
                  /*建立兩個堆:(1)一個大根堆,保存所有整數(shù)中較小的1/2;一個小根堆,保存所有整數(shù)中較大的1/2;
                    (2)并且,依次添加元素過程中,兩個堆大小的差的絕對值不能超過1;*/

                  
                  //第一元素加入大根堆
                  if(heap1.size()==0){
                      heap1.push(num);
                      return;
                  }
                  
                  if(num<=heap1.top()){
                      //第二個元素比大根堆的頂小
                      heap1.push(num);
                          
                       //大根堆元素過多
                      if(heap1.size()-heap2.size()>1)
                      {
                          int temp = heap1.top();
                          heap1.pop();
                          heap2.push(temp);//大根堆彈出頂?shù)叫「?
                      }
                      
                  }
                  else{
                      //第二個元素比大根堆的頂大,直接進入小根堆
                      heap2.push(num);
                      
                      //小根堆元素過多
                      if(heap2.size()-heap1.size()>1)
                      {
                          int temp = heap2.top();
                          heap2.pop();
                          heap1.push(temp);//小根堆彈出頂?shù)酱蟾?
                      }
                  }
                  
              }
              
              double findMedian() {
                  //輸入的元素為奇數(shù)個
                  if(heap1.size() > heap2.size())
                      return heap1.top();
                  else if(heap1.size() < heap2.size())
                      return heap2.top();
                  
                  //輸入的元素個數(shù)為偶數(shù)
                  else
                      return (heap1.top()+heap2.top())/2.0;
                     //取大根堆、小根堆的堆頂元素取平均值,即為所求全局中位數(shù)
              }
              
          private:
              priority_queue<int> heap1;//默認(rèn),大根堆
              priority_queue<int,vector<int>,greater<int>> heap2;//小根堆(升序序列)
              
          };


          好了,今天的文章就到這里,如果覺得有所收獲,請順手點個在看或者轉(zhuǎn)發(fā)吧,你們的支持是我最大的動力 。

          上期推文:
          LeetCode1-280題匯總,希望對你有點幫助!
          LeetCode刷題實戰(zhàn)281:鋸齒迭代器
          LeetCode刷題實戰(zhàn)282:給表達(dá)式添加運算符
          LeetCode刷題實戰(zhàn)283:移動零
          LeetCode刷題實戰(zhàn)284:頂端迭代器
          LeetCode刷題實戰(zhàn)285:二叉搜索樹中的順序后繼
          LeetCode刷題實戰(zhàn)286:墻和門
          LeetCode刷題實戰(zhàn)287:尋找重復(fù)數(shù)
          LeetCode刷題實戰(zhàn)288:單詞的唯一縮寫
          LeetCode刷題實戰(zhàn)289:生命游戲
          LeetCode刷題實戰(zhàn)290:單詞規(guī)律
          LeetCode刷題實戰(zhàn)291:單詞規(guī)律II
          LeetCode刷題實戰(zhàn)292:Nim 游戲
          LeetCode刷題實戰(zhàn)293:翻轉(zhuǎn)游戲
          LeetCode刷題實戰(zhàn)294:翻轉(zhuǎn)游戲II

          瀏覽 69
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  97男人天堂 | 黄色无码视频在线客服 | 夜夜躁很很躁日日躁2021 | 久久久久久久久久久国产 | 黄色成人A片 |