#arrays #c #algorithm #verification
#массивы #c #алгоритм #проверка
Вопрос:
Проверьте, существует ли индекс 0 <= k < n - 2
, такой, что элементы массива A[]
, перемещаемые по часовой стрелке по k
индексам, образуют обратный битонический массив. Мой подход к выполнению этого за O (n) время сложности:
bool is_antibitonicable(int A[], int n) {
// returns if there is such index k that
// after moving clockwise k elements of array
// A[], that array is reverse bitonic
// - strictly decreasing then strictly
// increasing
if (n < 3)
return false;
// if is_increasing[i] == 1 means this part of A[] is increasing,
// == 0 means that part of A[] is decreasing, == -1 default
int is_increasing[3] = { -1, -1, -1 };
for (int i = 0, j; i < n - 1;) {
if (A[i] < A[i 1]) { // if A[] is increasing
j = 0;
while (j < 3 amp;amp; is_increasing[j] != -1)
j ;
if (j == 3)
return false;
is_increasing[j] = 1;
while (i < n - 1 amp;amp; A[i] < A[i 1])
i ;
}
else if (A[i] > A[i 1]) { // check if decreasing
j = 0;
while (j < 3 amp;amp; is_increasing[j] != -1)
j ;
if (j == 3)
return false;
is_increasing[j] = 0;
while (i < n - 1 amp;amp; A[i] > A[i 1])
i ;
}
else // sequence of A[] is neither increasing nor decreasing
return false;
}
// if A[] is only increasing/decreasing
if (is_increasing[1] == is_increasing[2])
return false;
// if A[] is increasing->decreasing->increasing check if increasing
// parts can be merged into one increasing sequence
if (is_increasing[0] == 1 amp;amp; is_increasing[1] == 0 amp;amp; is_increasing[2] == 1)
return (A[0] > A[n - 1]);
// decreasing->increasing->decreasing
if (is_increasing[0] == 0 amp;amp; is_increasing[1] == 1 amp;amp; is_increasing[2] == 0)
return (A[0] < A[n - 1]);
return true; // increasing -> decreasing or opposite
}
Я был бы очень рад, если бы кто-нибудь мог взглянуть на мое решение и прокомментировать, кажется ли оно правильным или как это сделать лучше, любая обратная связь будет оценена.
Комментарии:
1. Напишите кучу тестовых примеров и посмотрите, проходит ли он
2. @EugeneSh. конечно, я это сделал, просто любопытно, не упускаю ли я что-то или делаю что-то ненужное 😉
3. Что должно означать «перемещение (элементов) массива по часовой стрелке «?
4. @Armali вращение по часовой стрелке, например, 1,2,3,5 -> 3,5,1,2 для k == 2.
5.Термин по часовой стрелке подразумевает движение по кругу. Не существует общего отображения массива на окружность; массив обычно изображается вдоль (направленной) прямой линии. Обычный термин для вашего описанного преобразования — поворот влево или вправо (в вашем примере не ясно, какое направление вы имеете в виду).
Ответ №1:
Ваше решение выглядит неплохо, но оно работает неправильно return false
// if A[] is only increasing/decreasing
. Такую последовательность всегда можно превратить сначала в уменьшающуюся, а затем в увеличивающуюся, повернув на единицу в правильном (соответствующем) направлении.
Комментарии:
1. строго возрастающая последовательность не может быть превращена в обратную битоническую последовательность без изменения порядка части последовательности, если я не ошибаюсь, возможно, я недостаточно хорошо или неправильно объяснил проблему в своем сообщении.
2. Я думаю, вы ошибаетесь; рассмотрим [1, 2, 3, 4], повернутые вправо на 1 => [4, 1, 2, 3]. Разве это не обратная битоническая последовательность ?