2012-10-31 5 views
7

ようアレイにおいて(i、j)の対の合計数を見つけるよう私<j and a[i]> [J]配列で(i、j)の対の合計数を見つける必要がある、問題に言及したように

(1) **i<j** 
(2) **a[i]>a[j]** 

ここで、iとjは配列のインデックスです。スペースの制約はありません。

私の質問は、私は、質問と明確だ願ってい

1) Is there any approach which takes less than O(N^2) time? 
2) if so what is least complexity ? 
3) How do we prove that ? 

です。 O(N^2)時間がかかるブルートフォアを使用している質問を行う

一つの方法を以下のように

私のアプローチがあります。

しかし、私は私の第二の直感がある

直観 1) For sorting an array in ascending order conditions we have are : for i<j , a[i]<a[j] which is similar to my question . I also read that sorting has lower bound of Omega(n log n) . So my question should also have Omega(n log n) . I may be completely wrong if so please correct me .

を次のように私の勘のためのO(NlogN)sollution【選択理由がある時に、少なくともこの質問へのより良い最適化された解決策があるはずだと思います:4,9,7,3,2,1,8,12

を我々はiと、要素4の条件i<j , a[i]>a[j]上記で計算:

は、次のように我々は、素子のアレイがあると= 0は4を指し、jの可能な値はa [0]> a [3]、a [0]> a [4]、a [0]> a [5]今の私の(i、j)ペアの合計は3です。 次回、i(インデックス)を1に増やすと、jの可能性のある値は2,3,4,5,6になります。しかし、i = 0(a [i] = 4)のとき、[i = 0]より小さい3つの要素を計算しました。これはa [i = 1]より小さくなります。不要な計算を取り除くことができれば、複雑さをO(N^2)よりも小さくすることができ、そうでなければO(N^2)より小さい解は存在しない。しかし、解決策が存在すれば、私たちはそれをどうやって行うのですか。私はグラフを作成しようとしましたが、私の努力は無駄です。

アプローチ1)In-order to obtain O(nlogn) complexity I think we need to tweak around quick sort or merge sort to get solution but problem here is, if we sort the array we loose the actual positions of elements.

アプローチ2)In-order to get solution in O(NlogN) time I think using tree we may get the optimised sollution . I didn't get any clue.

アプローチ3)If there exists any O(N) time algorithm it should be with hashing . But in this case simple hashing doest work .

だから、私は正しいどのアプローチが最適化されたsollutionにつながる場合には(正しい上記の直感やアプローチのどの教えてくださいそしてどうやって)。

+0

「* O未満(N^2)*」を意味しますか?私は技術的にO(N * 2)はO(N)と同じものであり、「O(N2)」の意味を明確にしていないからです。 – RBarryYoung

+0

はい私はO(N^2)を意味します – Imposter

+0

あなたはそのようなペアのカウントを見つけようとしているのですか、それらを列挙しようとしていますか? –

答えて

9

hereのように、マージソートに似たアルゴリズムで反転ペアをカウントできます。

考えてみると、配列をソートしてカウントする際に、各ステップでいくつの逆位が変更されたかを考えます。


異なるアプローチは、順序統計ツリーを使用することです。このツリーに配列の要素を順番に挿入し、各挿入後に、挿入された要素の前にいくつの要素があるかを確認します。

注文統計ツリーの代替品はIndexable skiplistです。


どちらのアルゴリズムもO(N log N)時間の複雑さを持っています。

逆数のおおよその数を得るには、O(N)時間の複雑さがありますが、いくつかの制限があります。マージソートが変更されたのと同じ方法でBucket sortを変更することができます。

Bucketソートの「散布」フェーズでは、バケットの最後に要素を挿入しながら(各バケットの要素は元の順序で残っています)、大きな要素のバケットの要素数を見積もる必要があります。

バケットソートの「ソート」フェーズでは、(同じ方法で)ソートアルゴリズム(挿入ソート、おそらく)を変更する必要があります。要素を適切な場所に挿入している間に、ジャンプした他の要素の数を数える必要があります。

制限事項として、このアルゴリズムは数字(またはオブジェクトで簡単に数値に変換可能)のみで動作し、これらの数値がどのように分配されるかを事前に知っておく必要があります。したがって、一様に分布した整数の配列がある場合、このアルゴリズムは正しく動作するはずです。

+0

注文統計情報のツリーは良いアイデアのように聞こえます。それは次のようなものですか?バイナリ検索ツリー。各ノードは、より大きな要素を含む右側のサブツリーの子の数を追跡します。挿入はツリーを横断する際にこのカウントを更新し、ツリーを下っていくときにこれらのカウントから見いだされる反転の数もカウントします。それは大体正しいですか? – Paresh

+0

@Paresh:そうです。ただし、各ノードは、それがルートとなるサブツリー内のノード数を追跡します。 –

+0

@EvgenyKluev:良い解決策。スペース要件がないので、適切なハッシュ(二重またはそれ以上の)関数を数える問題はO(N)で作業する必要があるからだと思います。 – Imposter

3

このようなペアは、配列内の逆位数と呼ばれます。これは、配列がどのくらい近くにソートされるかを示す1つの尺度です。マージソートを変更して、O(nlogn)時間内の反転数を効率的に数えることができます。詳細はthisを参照してください。

関連する問題