Ссылка на проблему: здесь

В этой задаче нам дан массив, в котором каждый элемент на позиции обозначает, сколько людей он подкупил, чтобы они пришли на текущую позицию.

Например: в q = [1, 4, 2, 3, 5],
Мы можем сказать, что 1 и 5 никого не подкупили, следовательно, они находятся в исходном положении. Кроме того, 4 подкупил 2 и 3, чтобы добраться до позиции 2.

Также есть условие, что ни один человек не может дать взятку более чем 2 людям.

Чтобы решить эту проблему, нам просто нужно знать, сколько человек подкупил человек, чтобы достичь своего нынешнего положения. Если внимательно присмотреться, эта проблема похожа на задачу подсчета инверсий с условием, что элемент нельзя переместить более чем на 2 позиции от его текущей позиции, что делает ее еще проще.

Подход к решению

Сначала мы начинаем с последнего элемента массива и переходим к первому элементу.
Для каждого элемента массива мы проверяем, смещен он или нет, т.е. (A[i] == i+1) , если он не смещен, мы продолжаем нашу итерацию, иначе мы делаем следующие шаги (для элемента в позиции i массива):
а) если A[i-1] == текущая позиция, т.е. A[i ] подкупил A[i+1], мы добавим 1 к нашему . результат и поменять местами оба элемента.
б) Если A[i-2] == текущей позиции, т.е. A[i] подкупил A[i-1] и A[i-2], мы добавим 2 к наш результат и поменять местами элементы, чтобы они достигли исходного состояния.

Код:

void minimumBribes(vector<int> q) {
    int n = q.size();
    int result = 0;
    for(int i = n - 1; i >= 0; i--) {
        if(q[i] != i+1) {
            if ((i-1 >= 0) && (q[i-1] == i+1)) {
                result += 1;
                q[i-1] = q[i];
                q[i] = i+1;
            } else if((i-2 >= 0) && (q[i-2] == i+1)) {
                result += 2;
                q[i-2] = q[i-1];
                q[i-1] = q[i];
                q[i] = i+1;
            } else {
                cout<<"Too chaotic"<<endl;
                return;
            }
        }
    }
    cout<<result<<endl;
    return;
}

Временная сложность: O(n).