數據結構問題集錦 - Find Median from Data Stream

臨近期末,鴨梨山大啊,就不多說了。這道題的要求就是,給定一串輸入,在中間任何一個時候,都能夠求出添加到一半的序列的中位數。

大概考慮一下,如果用動態數組來進行元素插入的話,盡管這樣查詢中位數的復雜度為O(1),由于每一次插入都是O(n),因而總復雜度為O(n^2),顯然遭不住。如果用鏈表的話,插入單次還是O(n),而且求中位數反而更不是O(1)了,也不行。這時候注意到我們需要一個有序的序列來求中位數,所以可以建兩個set,分別存放左半和右半序列,由于set本身數據是有序的,這樣很容易就能查找到中位數了。

于是就可以寫出如下代碼:

 1 template <typename T>
 2 T last(set<T> _set)
 3 {
 4     return *(_set.rbegin());
 5 }
 6 
 7 template <typename T>
 8 T first(set<T> _set)
 9 {
10     return *(_set.begin());
11 }
12 
13 class MedianFinder {
14 private:
15     set<int> left, right;
16 public:
17     //Adds a number into the data structure.
18     void addNum(int num) {
19         //Add new number first
20         if (left.empty()||(num<=last(left)))
21             left.insert(num);
22         else
23             right.insert(num);
24         
25         //Arrange left and right queue
26         if (left.size()>=right.size()+2)
27         {
28             right.insert(last(left));
29             left.erase(last(left));
30         }
31         else if (left.size()<right.size())
32         {
33             left.insert(first(right));
34             right.erase(first(right));
35         }
36     }
37 
38     //Returns the median of current data stream
39     double findMedian() {
40         if (left.size()==right.size())
41             return (last(left)+first(right))/2;
42         else
43             return last(left);
44     }
45 };

大家都知道C++中set是用紅黑樹實現的,于是每一次addNum都應該是O(log n)復雜度,findMedian函數寫的其實不夠好,因為每次添加過后其實都可以記錄下當前的中位數,避免到set中去查找最后一項(現在復雜度是O(log n),如此重新設計之后能變成O(1))

不過悲催的是Leetcode還是Time Limit Exceeded了,果然我是算法渣啊...

?

轉載于:https://www.cnblogs.com/lqf-96/p/find-median-from-data-stream.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375223.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375223.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375223.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

所處理的數據在什么地方 有多長 如何定義 如何尋找

處理的數據在什么地方&#xff1a; 立即數(idata)1,3,10,3F 寄存器AX,AL,BX 內存單元,可用尋址方式給出DS:[idata],ds:[0]處理的數據有多長: MOV AX,1 ;字操作 MOV AL,1 ;字節操作 MOV BYTE PTR DS:[0],1 ;字節操作 MOV WORD PTR DS:[0],1 ;字操作 PUSH/POP 進行的是字操作 數據…

invoke偽指令

通過反匯編helloworld對話框來看invoke偽指令 invoke是調用WinAPI的偽指令 把上一個helloworld對話框編譯并連接成hello.exe然后用OD打開得到下圖 前文說過ML.EXE編譯invoke時會把invoke的參數PUSH入棧和一個CALL,在代碼段中只有兩個invoke指令 invoke MessageBox,NULL,offset …

Azure Virtual Network, 虛擬網絡

云上的虛擬網絡把不同用戶完全的隔離開來。同時可以自己對虛擬網絡進行定制&#xff0c;設置各種安全訪問策略&#xff0c;配置load balancer等等。 在新的基于Azure Resource Manager (ARM)的部署方式中&#xff0c;虛擬網絡已經是默認設置了。也就是說在通過ARM部署的VM&…

百度地圖API的第一次接觸——自定義控件

1.定義一個控件類&#xff0c;即function function ZoomControl(){ // 設置默認停靠位置和偏移量 this.defaultAnchor BMAP_ANCHOR_TOP_LEFT; this.defaultOffset new BMap.Size(10, 10); } 2.通過JavaScript的prototype屬性繼承于BMap.Control ZoomControl.pr…

include語句

程序用到MessageBox和ExitProcess函數它們分別在user32..dll和Kernel32.dll中 那么就必須在程序中使用include語句包含這兩個庫文件,此時程序中可以使用user32..dll和Kernel32.dll中所有的函數 include相當于java中import導入包語句

Spring MVC Controller與jquery ajax請求處理json

在用 spring mvc 寫應用的時候發現jquery傳遞的【json數組對象】參數后臺接收不到&#xff0c;多訂單的處理&#xff0c;ajax請求&#xff1a; var cmd {orders:[{"storeId":"0a1", "address":"西斗門路2號", "goods":[{&…

課堂例子解答

Editbox 等價類劃分測試用例例子 要求輸入1到6個英文字符或數字&#xff0c;按OK結束并輸入。 其中有效等價類包括:1.長度1-6&#xff0c;2.a-z,A-Z,0-9 無效等價類包括&#xff1a;1.長度0或大于6&#xff0c;2.輸入字母數字以外的字符&#xff0c;控制字符&#xff0c;標點符…

從代碼里提取的測試需求

服務器端的測試&#xff0c;軟件需求基本等于產品說明書&#xff0c;只有大概&#xff0c;沒有詳盡。再需求不充分的情況下&#xff0c;我們可以從哪些方面來挖掘測試需求呢&#xff1f; 現已知需求&#xff1a;服務器支持對客戶端的版本升級&#xff0c;存在兩種升級規則&…

PUSH/POP

棧操作指令PUSH 寄存器/段寄存器/內存單元POP 寄存器/段寄存器/內存單元PUSH AX1)SPSP-2 ,SS:SP指向新的內存單元2)將AX送入SS:SP指向的內存單元POP AX1)將SS:SP指向的內存單元處的數據送入AX中2)SPSP2

Android Ant 和 Gradle 打包流程和效率對照

一、Ant 打包&#xff1a;&#xff08;下載ant、配置環境變量就不說了&#xff09; 1、進入命令行模式&#xff0c;并切換到項目文件夾。運行例如以下命令為ADT創建的項目加入ant build支持&#xff1a; android update project -p . -t "android-17" 2、build腳本默…

讀軟件工程這本書的感悟(第一次作業)

在還沒上這門課之前&#xff0c;我認為軟件工程是讓我們學會編寫軟件&#xff0c;但是在看到這本書后&#xff0c;我才知道我們學的不是如何的開發軟件&#xff0c;而是在學習開發和維護軟件&#xff0c;以及如何把經過時間考驗而證明正確的管理技術和當前能夠得到的最好的技術…

請大家編譯連接并執行一下

由于是筆記&#xff0c;也許記得有點糟糕&#xff0c;也許班門弄斧沒有獨到見解 &#xff0c;見諒見諒

KVC和KVO

OC中的一個比較有特色的知識點&#xff1a;KVC和KVO一、KVC操作OC中的KVC操作就和Java中使用反射機制去訪問類的private權限的變量&#xff0c;很暴力的&#xff0c;這樣做就會破壞類的封裝性&#xff0c;本來類中的的private權限就是不希望外界去訪問的&#xff0c;但是我們這…

8086加法指令ADD

加法指令ADD(ADDition) ADD OPRD1,OPRD2 ;OPRD1<--OPRD1OPRD2 ;完成OPRD1與OPRD2相加 ,結果保存在OPRD1中CODE SEGMENT MOV AX,1 MOV BX,2 ADD AX,BX ;AX<--AXBX ,結果AX3CODE ENDS參與運算的操作數類型必須保持一致,同為字節或字可組合以下幾種形式&…

Fragment基礎講解

//新建一個碎片public class LeftFragment extends Fragment { Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 加載一個碎片界面 View view inflater.inflate(R.layout.leftfragment, container, false)…

[bzoj1012](JSOI2008)最大數maxnumber(Fenwick Tree)

Description 現在請求你維護一個數列&#xff0c;要求提供以下兩種操作&#xff1a; 1、 查詢操作。語法&#xff1a;Q L 功能&#xff1a;查詢當前數列中末尾L個數中的最大的數&#xff0c;并輸出這個數的值。限制&#xff1a;L不超過當前數列的長度。 2、 插入操作。語法&…

javaScript轉換日期合格式

javascript如何將時間日期轉換為Date對象:有時候需要講一個字符串型的時間日期轉換為Date時間對象&#xff0c;下面就通過一個簡單的實例提供一種解決方案&#xff0c;當然也是一種思路&#xff0c;可以進行一定的變通&#xff0c;以達到舉一反三的效果。例如這里有一個時間日期…

8086減法指令SUB

減法指令SUB(SUBtraction) SUB OPRD1,OPRD2 ; OPRD1<-- OPRD1-OPRD2 都影響FLAG標志寄存器,同樣的包含兩種含義(有符號減法和無符號減法)

奇怪吸引子---Dadras

奇怪吸引子是混沌學的重要組成理論&#xff0c;用于演化過程的終極狀態&#xff0c;具有如下特征&#xff1a;終極性、穩定性、吸引性。吸引子是一個數學概念&#xff0c;描寫運動的收斂類型。它是指這樣的一個集合&#xff0c;當時間趨于無窮大時&#xff0c;在任何一個有界集…

8086 INC, DEC

INC OPRD ;OPRD<--OPRD1 ;自加1指令code segmentmov ax,0inc ax ;ax<--ax1 ,ax1inc ax ;ax<--ax1 ,ax2code endsDEC OPRD ;OPRD<--OPRD-1 ;自減1指令code segmentmov ax,5dec ax ;ax<--ax-1 ,ax4 code ends