Оптимизация и рефакторинг алгоритма
Дан массив чисел. Нужно его сдвинуть циклически на K позиций влево, не используя других массивов. Сделал для неубывающего массива. Есть ли универсальный способ
public static int[] DoShift(int[] arrayToShift, int countOfShifts)
{
countOfShifts %= arrayToShift.Length;
for (int i = countOfShifts; i < arrayToShift.Length; i++)
{
(arrayToShift[i], arrayToShift[i - countOfShifts]) = (arrayToShift[i - countOfShifts], arrayToShift[i]);
}
for (int i = arrayToShift.Length - countOfShifts; i < arrayToShift.Length - 1; i++)
{
for (int j = i + 1; j < arrayToShift.Length; j++)
{
if (arrayToShift[i] > arrayToShift[j])
{
(arrayToShift[i], arrayToShift[j]) = (arrayToShift[j], arrayToShift[i]);
}
}
}
return arrayToShift;
}
Ответы (1 шт):
Автор решения: MBo
→ Ссылка
Для сдвига на 1 позицию влево можно использовать простой алгоритм - запомнить первый элемент, сдвинуть все остальные, поставить запомненный на последнее место. Для сдвига на небольшое K можно использовать это же K раз, что приводит к сложности O(KN), но в общем случае есть чудесный линейный алгоритм O(N):
Перевернуть подмассив из первых K элементов (производится на месте)
Перевернуть подмассив из последних N-K элементов
Перевернуть весь массив
3 8 1 2 4 7 K=3
1 8 3 2 4 7
1 8 3 7 4 2
2 4 7 3 8 1