これでできます。結果は提案された出力とは異なりますが、指定されたルールと同じです (問題のテキストには「並べ替え」という単語が含まれていません0
。1
それらを「圧縮」する必要はありません)。「圧縮」するのはもう少し複雑です。
static void Main(string[] args)
{
var input = new[] { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1 };
var lastEvenToMove = -1;
var lastOddToMove = -1;
for (int i = 0; i < input.Length; i++)
{
bool needEven = i % 2 == 0;
bool isEven = input[i] == 0;
if (needEven == isEven)
{
continue;
}
if (needEven)
{
if (lastEvenToMove != -1)
{
var old = input[lastEvenToMove];
input[lastEvenToMove] = 1;
input[i] = 0;
lastEvenToMove = old;
}
else
{
input[i] = lastOddToMove;
lastOddToMove = i;
}
}
else
{
if (lastOddToMove != -1)
{
var old = input[lastOddToMove];
input[lastOddToMove] = 0;
input[i] = 1;
lastOddToMove = old;
}
else
{
input[i] = lastEvenToMove;
lastEvenToMove = i;
}
}
}
while (lastEvenToMove != -1)
{
var old = input[lastEvenToMove];
input[lastEvenToMove] = 0;
lastEvenToMove = old;
}
while (lastOddToMove != -1)
{
var old = input[lastOddToMove];
input[lastOddToMove] = 1;
lastOddToMove = old;
}
Console.WriteLine(@"{{{0}}}", String.Join(", ", input.Select(p => p.ToString())));
}
オッズのスタックと移動が必要な偶数の要素のスタックを保持し、奇数/偶数が必要なときにこれらを使用します。2 つのスタックは入力配列に保持されるため、余分なスペースはありません (2 つのスタックの 2 つの「先頭」、つまり 2 つの余分な整数を除く)。O(1.5n)
最悪のケースは、時間 (たとえば、すべての要素が1
であり、要素の半分がスタックに「置かれ」、空きスペースがなかったためにリセットする必要がある) とスペースのためだと思いますO(1)
。
出力:
{0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1}