中位數 ii
數字是不斷進入陣列的,在每次新增乙個新的數進入陣列的同時返回當前新陣列的中位數。
說明中位數的定義:
樣例持續進入陣列的數的列表為:[1, 2, 3, 4, 5],則返回[1, 1, 2, 2, 3]
持續進入陣列的數的列表為:[4, 5, 1, 3, 2, 6, 0],則返回[4, 4, 4, 3, 3, 3, 3]
持續進入陣列的數的列表為:[2, 20, 100],則返回[2, 2, 20]
開始想到用線性的思想,意料之中的tle。。。
最大最小堆演算法:
複雜度時間 o(nlogn) 空間 o(n)
思路維護乙個最大堆,乙個最小堆。最大堆存的是到目前為止較小的那一半數,最小堆存的是到目前為止較大的那一半數,這樣中位數只有可能是堆頂或者堆頂兩個數的均值。而維護兩個堆的技巧在於判斷堆頂數和新來的數的大小關係,還有兩個堆的大小關係。我們將新數加入堆後,要保證兩個堆的大小之差不超過1。先判斷堆頂數和新數的大小關係,有如下三種情況:最小堆堆頂小於新數時,說明新數在所有數的上半部分。最小堆堆頂大於新數,但最大堆堆頂小於新數時,說明新數將處在最小堆堆頂或最大堆堆頂,也就是一半的位置。最大堆堆頂大於新數時,說明新數將處在所有數的下半部分。再判斷兩個堆的大小關係,如果新數不在中間,那目標堆不大於另乙個堆時,將新數加入目標堆,否則將目標堆的堆頂加入另乙個堆,再把新數加入目標堆。如果新數在中間,那加到大小較小的那個堆就行了(一樣大的話隨便,**中是加入最大堆)。這樣,每次新加進來乙個數以後,如果兩個堆一樣大,則中位數是兩個堆頂的均值,否則中位數是較大的那個堆的堆頂。
class solution
left.insert(tmp);
} else
right.insert(tmp);
}flag = !flag;
res.push_back(*left.rbegin());
}return res;
} /*方法二:線性處理,但是會超時*/
vectormedianii_2(vector&nums) //if
int len = nums.size();
vectorret,v;
v.push_back(nums[0]);
ret.push_back(nums[0]);
for(int i=1; i&nums)
//if
int lhs = 0 , rhs = nums.size()-1;
int mid = (lhs + rhs) / 2;
int idx = partition(nums, lhs , rhs);
while(idx != mid && lhs <= rhs)
else//if
idx = partition(nums, lhs , rhs);
}//while
return nums[idx];
}int partition(vector&nums, int left, int high)
//if
int low = left-1, pivot = nums[high];
for(int i=left; i
資料流中的中位數python 資料流中的中位數
python用的自己實現的最大和最小堆的class,getmedian需要加個引數,否則python版會報錯。coding utf 8 最小堆 class minheap def init self self.minheap def len self return len self.minheap ...
資料流中的演算法
資料流統計功能上線後,為51nod提公升使用者體驗做出了很大的貢獻。但是新問題隨之而來,夾克老爺還想知道在乙個視窗內,訪問次數最多使用者 即視窗內的眾數 如果有多個眾數,取使用者id最小的乙個。視窗的意思是乙個固定長度的區間!input 第一行為整數n,k。1 n 5 10 6,1 k 1000 n...
資料流中的中位數
資料流中的中位數 如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。解題思路 維護乙個大堆和乙個小堆,大堆表示序列前一半數,小堆表示序列後一半數,保持兩個堆的元素個...