大要素のK P106配列(leetcode 215)

A:問題解決のためのアイデア

問題を解決する最も簡単な方法は、アレイが降順、次いでK-1の要素を削除することです。時間:O(N *ログ(n))は、スペース:O(1)

私たちは、実践の以下の2種類を記述します。

方法一:配列への配列、配列要素を横断したらレッツは、トップkの最小ヒープを維持するが、ヒープの最後の要素は、大きな要素所与最初のKです。時間:O(N *ログ(K))クイックソートよりも、スペース:O(K)

方法2:及び、パーティション機能の分割を必要とする最初の(基準の選択は、アルゴリズムの時間複雑さの間の関係がより重要である)のデータを選択し、これは、アレイの左側に基準素子よりも大きくなるクイックソートと幾分類似しており、アレイの右側に基準要素よりも小さくなります。(順序を変更することができる、それが右に参照要素よりも左に基準要素よりも小さくてもよい。)、およびアルゴリズムの最良の平均時間計算量は次のとおりO(N)、最悪の(すなわち、配列配置)時間複雑である場合に小から大に始まる:O(N ^ 2)、空間的複雑度はO(1)我々は、アレイ内のデータを使用することができる確率的アルゴリズムは、ランダムそうであってもよいが破壊されます。時間計算量はO(N)となります。実際のデータは主にランダムな配置であるため、そのようなアルゴリズムの正当な理由の実際のアプリケーションでは、アルゴリズムの時間複雑度は、次のとおり時間:O(n)は、宇宙:O(1)

2:完全なコード例(C ++とJava版のバージョン)、

方法1個のC ++:

クラスのソリューション
{ 
プライベート
    PRIORITY_QUEUE < int型、ベクトル< int型 >、大きい< int型 >> のminheap。
公共INT findKthLargest(ベクトル< INT >&NUMS、INT K)
    { 
        ためINT NUM:NUMS)
        { 
            場合(minHeap.size()< K)
            { 
                minHeap.push(NUM)。
            } 
            そう であれば(NUM> minHeap.top())
            { 
                minHeap.pop()。
                minHeap.push(NUM)。
            } 
        } 

        を返す)(minHeap.topします。
    } 
}。

この方法の一つのJava:

クラスソリューション
    { 
        プライベートキュー<整数> =のminheap 新しい優先度つきキュー<> (); 

        公共 INT findKthLargest(INT [] NUMS、INT K)
        { 
               ためINT NUM:NUMS)
               { 
                   場合(minHeap.size()< K)
                   { 
                       minHeap.add(NUM)。
                   } 
                   そうで あれば(NUM> minHeap.peek())
                   { 
                       minHeap.poll()。
                       minHeap.add(NUM)。
                   } 
               }

               リターンminHeap.peek(); 
        } 
    }

メソッドの2つのC ++:

クラス解決
{ 
プライベートint型のパーティション(ベクトル< INT >&NUMS、int型の低、INTの高い)
    { 
        int型ピボット= NUMS [低]は、iが低い、J = = 高;
        一方、(I < J)
        { 
            ながら(I <J && NUMS [J] <ピボット)j-- もし(I < J)スワップ(NUMS [I]、NUMS [J])。
            一方 ++(I <J && NUMS [I]> =ピボット)I もし(I < J)スワップ(NUMS [I]、NUMS [J])。
        } 

        を返す私は、
    }
公共INT findKthLargest(ベクトル< INT >&NUMS、int型K)
    { 
        int型の低= 0、ハイ= nums.size() - 1 ;
        一方(低<= 高)
        { 
            int型、P = パーティション(NUMS、低、高)。
            もし(P == K - 1戻りNUMS [P]。
            他の 場合(P> K - 1)高= P - 1 他の低= P + 1 ; 
        } 

        リターン -1 ; 
    } 
}。

 

この方法の2つのJava:

 クラスソリューション
    { 
        プライベート ボイドスワップ(INT [] NUMS、int型 I、INT J)
        { 
            int型の TEMP = NUMS [I]。
            NUMS [I] = NUMS [J]。
            NUMS [J] = TEMP。
        } 

        プライベート int型 partion(INT [] NUMS、INT低い、INT 高いが)
        { 
            int型のピボット= NUMS [低]は、iは=低、J = 高いです。
            一方、(I < J)
            { 
                ながら(I <J && NUMS [J] <ピボット)j--;
                もし(I < J)スワップ(NUMS、i、j)は、
                一方 ++(I <J && NUMS [I]> =ピボット)I もし(I < J)スワップ(NUMS、i、j)は、
            } 

            を返す私は、
        } 

        公共 INT findKthLargest(INT [] NUMS、int型K)
        { 
              int型の低= 0、ハイ= nums.length- 1 一方(低<= 高)
              { 
                  int型、P = partion(NUMS、低、高)。
                  もし(P == K- 1戻りNUMS [P]。
                  それ以外の 場合(P> K- 1)高= P- 1 ;
                  他の低= P + 1 ; 
              } 

              リターン - 1 
        } 
    }

 

おすすめ

転載: www.cnblogs.com/repinkply/p/12662623.html