配列内の各要素のより小さな要素の数を効率的に見つける


9

私はこの問題に行き詰まっています:

最初の自然数の配列がランダムに並べ替えられると、配列が構築され、 はよりも小さいからまでの要素数になります。。 n B B k A 1 A k 1 A k AnBB(k)A(1)A(k1)A(k)

i)が与えられれば、時間でを見つけることができますか? ii)が与えられた場合、を時間で見つけることができますか?B O n B A O n ABO(n)
BAO(n)

ここで、です。具体的な例: | A 8 4 3 1 7 2 9 6 5 B 0 0 0 0 3 1 6 4 4 |B(1)=0

|A843172965B000031644|

誰か助けてもらえますか?ありがとう。


私はこれを見つけました:これらの問題アルゴリズムを提供する計算順列エンコーディング。少なくとも私は同じ問題だと思います。O(nlogn)
Realz Slaw

@Merbsあなたが与えたそのヒントはあなたが解決策を持っていることを意味しますか?
2012年

1
@AJed、それは私がアルゴリズムを持っていることを意味しますが、スペースのない単純なアルゴリズムの場合は、スペースが許可されている場合は必要です。現時点では、では不可能ではなく、どちらも同じアルゴリズムであることに傾倒しています。O(n2)O(nlogn)O(n)
Merbs 2012年

@Merbs。あなたのヒントが正しい軌道につながると思います。私も1つの解決策を持っています(あなたのヒントに従って)。分析には行くトリックがあると思います。トリックは、が1:からのみ行くという知識であると思います。O(n)An
2012年

2
このペーパーでは、アルゴリズムも示します。このためのアルゴリズムが存在しますか?O(nlogn)O(n)
Realz Slaw

回答:


1

からを決定する単純なアルゴリズム:BA

以下のための、の値を決定それぞれ比較することにより、するための 及びそれら満たすことがカウント。k=1,,nB(k)A(i)A(k)i=1,,kA(i)<A(k)

このアルゴリズムは、を他のすべてと比較し(回)、を他のと比較します。したがって、比較の総数は。しかし、それは私たちにできる最善のことではありません。たとえば、を見ると、比較を行う必要はありません。、これが最初の自然数であり、(順列に関係なく)小さい自然数が存在することが保証されているためです。どの程度?からをチェック代わりに、単にチェックことができます。あれは:A(1)n1A(2)n2(n1)(n2)2B(n)B(n)=A(n)1 nn1B(n1)A(1)A(n2)A(n)

以下のために、上記のアルゴリズムを使用します。以下のための 逆のアルゴリズムを使用しますかを決定最初にそれを設定することにより、、次に減算各エントリのためののために未満です。k=1,,n2k=n2,,nB(k)A(n)11A(i)i=k+1,,nA(k)

これにはステップ、これはまだです。また、からを構築ときに、場合、となることに注意してください。2×(n21)(n22)2=(n2)(n4)4O(n2)ABB(n)=A(n)1A(n)=B(n)+1

しかし、今はもっと巧妙に。スペースを追加したり、インプレースで並べ替えたりできる場合は、比較しながら数値を並べ替えることができます。例:

|A843172965S987432165B0000316|

それらすべてをチェックする(または順番にチェックする)代わりに、バイナリ検索を使用して各を決定することができます。ただし、ソートにはまだ時間がかかります。O n log n B(k)O(nlogn)


これはちょうど私の最初のアイデアでした。この問題は、私が最初に挙げたものよりも興味深いことに気づきました。そして、まだRealz Slawの調査結果を読む機会がなかったので、アルゴリズムがオフになっている可能性があります。
Merbs 2012年

0

各一度に1つずつ決定するのではなく、前向きにして各数値をだけ調べることができます。ただし、スペースを使用します。B(k)A n

|A123456789B800000000104000011112030001222230101123333407011233345320123444561901234445666012344567450123456784|

既に決定されているものを更新しないことで(つまり、最初のステップの後にを更新しても意味がありません)、さらに時間を節約できますが、最悪の場合、回8(n)(n+2)2


0

IとIIはどちらも、ここで説明した#next_greater_elementを使用して解決できます。しかし、問題よりも少し難しいですが、解決策の前に、次のより大きな要素を学ぶ必要があります。

  1. すべての要素のベクトルが要素という名前であるとます。次に、次に大きいアルゴリズムを右から左に実行しますが、要素を次に大きい要素インデックスに設定することをて、、が次に大きい要素である要素をプッシュします。次に、配列を左から右に繰り返し、次に ここで、はベクトルそののサイズ です。これは、次に大きいアルゴリズムがそれぞれ あり、また反復はS I I I A S I I B [ I ] = Σ X J = 0S I [ J ] + 1 X S I Θ N Θ N Θ N ASiiiASiiB[i]=j=0x(Si[j]+1)xSiΘ(n)Θ(n)Θ(n)

2番目の部分も同様で、で最も右の要素の値を取得できることに注意してください。 編集:私の解決策は間違っています解決策がないようです。o n O(1)o(n)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.