Информация об изменениях

Сообщение Re[8]: здачки с собеседования в yandex от 03.04.2021 23:56

Изменено 04.04.2021 0:36 Артём

Re[8]: здачки с собеседования в yandex
Здравствуйте, Pzz, Вы писали:

Б>>Переворачиваем сначала весь массив, а потом переворачиваем каждую часть.

Б>>Переворачиваем = переставляем в обратном порядке. Т.е. меняем первый элемент с последним, второй с предпоследним и т.д.

Pzz>Мне когда в реальной жизни понадобилось, я сделал рекурсивно: выбираем ту "половину", которая поменьше, и меняем ее местами с соседней с ней частью такого же размера. Потом во второй половине рекурсивно меняем ту часть, которую мы только что туда записали, и оставшуюся.


Pzz>[AAAA][BBBBB] -> [BBBB][AAAA][B] -> [BBBB][BAAAA]


Pzz>Про тройной переворот я не знал/не догадался. Но рекурсивный вариант вроде как делает меньше обращений к памяти (на каждом шаге одна из частей массива оказывается уже на своем окончательном месте).

Это двойной переворот.

Можно сделать циклический сдвиг, получится O(N):
[0..k), [k..n)
Как-то так, но нужно проверять правильность offset:

function swap_k<T>(a: T[], k: number) {
  const n = a.length;

  if (k === 0 || k === n - 1) {
    return;
  }
  const acc = a[k];
  const offset = n / 2 + n % 2;
  for (let i=0; i < n; ++i) {
     a[(k + i) % n] = a[(k + offset + i) % n];
  }
  a[k + off] = acc;
}
Re[8]: здачки с собеседования в yandex
Здравствуйте, Pzz, Вы писали:

Б>>Переворачиваем сначала весь массив, а потом переворачиваем каждую часть.

Б>>Переворачиваем = переставляем в обратном порядке. Т.е. меняем первый элемент с последним, второй с предпоследним и т.д.

Pzz>Мне когда в реальной жизни понадобилось, я сделал рекурсивно: выбираем ту "половину", которая поменьше, и меняем ее местами с соседней с ней частью такого же размера. Потом во второй половине рекурсивно меняем ту часть, которую мы только что туда записали, и оставшуюся.


Pzz>[AAAA][BBBBB] -> [BBBB][AAAA][B] -> [BBBB][BAAAA]


Pzz>Про тройной переворот я не знал/не догадался. Но рекурсивный вариант вроде как делает меньше обращений к памяти (на каждом шаге одна из частей массива оказывается уже на своем окончательном месте).

Это двойной переворот.

Можно сделать циклический сдвиг, получится O(N):
[0..k), [k..n)
Как-то так, но нужно проверять правильность offset:

function swap_k<T>(a: T[], k: number) {
  const n = a.length;

  if (k === 0 || k === n - 1) {
    return;
  }
  const acc = a[k];
  const offset = n / 2 + n % 2;
  for (let i=0; i < offset; ++i) {
     a[(k + i) % n] = a[(k + offset + i) % n];
  }
  a[k + off] = acc;
}