私はいくつかのアルゴリズムの割り当てに取り組んでおり、次のように求められました: O(n) の配列を要素 'r' または 'w' で並べ替えて、'r' が常に 'w' の前に来るようにしてください。したがって、入力が [w,r,w,r,w,r,w,w] のように見える場合、アルゴリズムの実行後、配列は [r,r,r,w,w,w,w,w] のようになります.
概念的には、これはすぐに非常に明確に思えました。最初の 'w' 要素の位置と最後の 'r' 要素の位置を保持する 2 つの境界変数を使用する必要がありました。
私のコードは次のようになります。
char[] A = new char[] { 'w', 'r', 'w', 'r', 'w', 'r', 'w', 'w' };
int lastRedPosition = A.Length - 1;
int firstWhitePosition = 0;
for (int i = firstWhitePosition ; i < A.Length; i++)
{
// determine the first red from the right e.g. the lastred, ending at the firstwhite position
for (int j = lastRedPosition; j > firstWhitePosition; j--)
{
if (A[j] == 'r')
{
lastRedPosition = j;
break;
}
}
for (int k = firstWhitePosition; k < lastRedPosition; k++)
{
if (A[k] == 'w')
{
firstWhitePosition = k;
break;
}
}
A[firstWhitePosition] = 'r';
A[lastRedPosition] = 'w';
}
ネストされた for ループにもかかわらず、直感的に O(n) で実行されると思います。これは、全体として、配列が 1 回だけトラバースされるためです。lastRedPosition 変数と firstWhitePosition 変数を使用して、どこにいたかを追跡しているためです。
ただし、同じネストされたforループのため、これをより正式に動機付けるのは難しいと思います...誰かが正しいdirectopmへのポインタを教えてもらえますか?