1. 程式人生 > 程式設計 >Vue中插槽和過濾器的深入講解

Vue中插槽和過濾器的深入講解

1. 題目

如何得到一個數據流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。

例如,

[2,3,4]的中位數是 3

[2,3] 的中位數是 (2 + 3) / 2 = 2.5

設計一個支援以下兩種操作的資料結構:

  • void addNum(int num) - 從資料流中新增一個整數到資料結構中。
  • double findMedian() - 返回目前所有元素的中位數。

2. 示例

示例1:

輸入:
["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"]
[[],[
1],[2],[],[3],[]] 輸出:[null,null,null,1.50000,null,2.00000]

示例2:

輸入:
["MedianFinder","addNum","findMedian","addNum","findMedian"]
[[],[2],[],[3],[]]
輸出:[null,null,2.00000,null,2.50000]

3. 題解

最初的想法是用TreeMap來儲存資料,key為輸入,value為數量。然後在查詢的時候查詢偶數查詢第n/2個數以及n/2 + 1個數。超時

然後使用大小堆的方式:

  • 定義一個小頂堆和一個大頂堆。小頂堆儲存大的一半,大頂堆儲存小的一半。
  • A儲存較大的一半,長度為N/2(N 為偶數) 或 (N + 1) / 2 (N 為奇數);
  • B儲存較小的一半,長度為N/2(N 為偶數) 或 (N - 1) / 2 (N 為奇數);

4. 實現

4.1 TreeMap(超時

 1 class MedianFinder {
 2 
 3     Map<Integer, Integer> ans;
 4     int len = 0;
 5 
 6     /** initialize your data structure here. */
 7     public MedianFinder() {
 8         ans =  new TreeMap<>();
 9     }
10 
11     public
void addNum(int num) { 12 ans.put(num, ans.getOrDefault(num, 0) + 1); 13 len++; 14 } 15 16 public double findMedian() { 17 int sum = 0; 18 if(len % 2 == 1) { 19 int index = len / 2 + 1; 20 for(int k : ans.keySet()) { 21 if(sum + ans.get(k) >= index) { 22 return k; 23 } 24 sum += ans.get(k); 25 } 26 } else { 27 int pre = len / 2, cur = len / 2 + 1; 28 System.out.println("輸入:" + pre + " " + cur); 29 int preValue = -50, curValue = -50; 30 for(int k : ans.keySet()) { 31 if(sum + ans.get(k) >= pre && preValue == -50) { 32 preValue = k; 33 } 34 if(sum + ans.get(k) >= cur && curValue == -50) { 35 curValue = k; 36 break; 37 } 38 sum += ans.get(k); 39 } 40 System.out.println("輸出:" + preValue + " " +curValue); 41 return (double)((preValue + curValue) / 2.0); 42 } 43 return 0; 44 } 45 } 46 47 /** 48 * Your MedianFinder object will be instantiated and called as such: 49 * MedianFinder obj = new MedianFinder(); 50 * obj.addNum(num); 51 * double param_2 = obj.findMedian(); 52 */
View Code

4.2 大小頂堆

 1 class MedianFinder {
 2     // 大小堆
 3     Queue<Integer> A, B;
 4     public MedianFinder() {
 5         A = new PriorityQueue<>(); // 小頂堆,儲存較大的一堆
 6         B = new PriorityQueue<>((x, y) -> (y - x)); // 大頂堆,儲存較小的一半
 7         B = new PriorityQueue<>((x, y) -> (y - x)); // 大頂堆,儲存較小的一半
 8     }
 9     // 建立大小頂堆,各儲存一半:
10     // A儲存較大的一半,長度為N/2(N 為偶數) 或 (N + 1) / 2 (N 為奇數);
11     // B儲存較小的一半,長度為N/2(N 為偶數) 或 (N - 1) / 2 (N 為奇數)
12     public void addNum(int num) {
13         // A.size() != B.size(),需向B新增一個元素。實現方法:將新元素num插入A,再將A堆頂元素插入至B;
14         // A.size() == B.size(),需向A新增一個元素,實現方法:將新元素num插入B,再將B堆頂元素插入至A;
15         if(A.size() != B.size()) {
16             A.add(num);
17             B.add(A.poll());
18         } else {
19             B.add(num);
20             A.add(B.poll());
21         }
22     }
23     public double findMedian() {
24         return A.size() != B.size() ? A.peek() : (A.peek() + B.peek()) / 2.0;
25     }
26 }
27 
28 /**
29  * Your MedianFinder object will be instantiated and called as such:
30  * MedianFinder obj = new MedianFinder();
31  * obj.addNum(num);
32  * double param_2 = obj.findMedian();
33  */
View Code

5. 結語

  努力去愛周圍的每一個人,付出,不一定有收穫,但是不付出就一定沒有收穫! 給街頭賣藝的人零錢,不和深夜還在擺攤的小販討價還價。願我的部落格對你有所幫助(*^▽^*)(*^▽^*)!

  如果客官喜歡小生的園子,記得關注小生喲,小生會持續更新(#^.^#)(#^.^#)。

但行好事 莫問前程