[LeetCode 295]データストリームから中央値を探します

中央値は、順序付けられた整数リストの中央値です。リストのサイズが偶数の場合は、中間の値ではありません。だから、中央値は、2つの中間値の平均値です。

例えば、

[2,3,4]、中央値は、 3

[2,3]、中央値は、 (2 + 3) / 2 = 2.5

以下の2つの操作をサポートするデータ構造を設計します。

  • 無効addNum(int型NUM) - データストリームからのデータ構造に整数値を追加します。
  • ダブルfindMedian() - 戻り、これまでのすべての要素の中央値。

 

例:

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

 

ファローアップ:

  1. ストリームからのすべての整数値が0と100の間であれば、どのようにそれを最適化するのでしょうか?
  2. ストリームからのすべての整数の99%が0と100の間であれば、どのようにそれを最適化するのでしょうか?

 

解決法1.新しい番号が追加されるたびに、ソート新しい配列と中央値を取得します。

ランタイム:oの和(I * iはログ)iについて:[1、N]。 

スペース:O(n)は、

 

BUDの最適化: 

ボトルネック:配列arrをソートするには、O(arr.length *ログarr.length)時間がかかります。  

不要な作業:ソート配列全体たびに、我々は、すべての必要はありませんにもかかわらず、 

非中央値の数字は、アレイ内のその右の順になるように。 

 

ソリューションは、新しい番号が追加されるたびに、新たな中央値を選択するために迅速な選択アルゴリズムを適用します。2.。

ランタイム:iに対するOの合計(I):[1、N]。

スペース:O(n)は、

 

私たちは、O(I)に(I * Iログ)Oから液1のボトルネックを改善しました。しかし、この解決策はまだありません 

最適な。我々はさらにそれを軽減することができます(i)をログに記録しますか? 

 

ソリューション3.動的に現在の中央値を維持するための最小と最大の優先順位キュー。新しい番号を追加します

to a priority queue takes O(log i) time, i is the current number of elements stored in the priority queue.

Runtime: Sum of O(log i) for i: [1, n], which is approximately O(n * log n)

Space: O(n)

 

Use the following invariants to maintain both max and min pq.

 

The max pq has 1 more element than the min pq if we've processed an odd number of elements;

They have the same number of elements if we've processed an even number of elements; 

 

class MedianFinder {
    private PriorityQueue<Integer> maxPq;
    private PriorityQueue<Integer> minPq;
    int size;
    /** initialize your data structure here. */
    public MedianFinder() {
        maxPq = new PriorityQueue<>(Collections.reverseOrder());
        minPq = new PriorityQueue<>();
        size = 0;
    }
    
    public void addNum(int num) {
        if(size == 0) {
            maxPq.add(num);
        }
        else {
            if(num <= maxPq.peek()) {
                maxPq.add(num);
            }
            else {
                minPq.add(num);
            }
            if(maxPq.size() - minPq.size() > 1) {
                minPq.add(maxPq.poll());
            }
            else if(minPq.size() > maxPq.size()) {
                maxPq.add(minPq.poll());
            }
        }
        size++;
    }
    
    public double findMedian() {
        if(size == 0) {
            return 0.0;
        }
        if(size % 2 != 0) {
            return maxPq.peek();
        }
        double sum = maxPq.peek() + minPq.peek();
        return sum / 2.0;
    }
}

 

Related Problems

Sliding Window Median

Median

Median of Two Sorted Arrays 

おすすめ

転載: www.cnblogs.com/lz87/p/6997513.html