Повернення списку за допомогою двох черг


12

Це питання натхнене існуючим питанням про те, чи можна моделювати стек, використовуючи дві черги з амортизованим часом за операцію стека. Відповідь, здається, невідома. Ось більш конкретне запитання, відповідне окремому випадку, коли перші операції PUSH виконуються спочатку, а потім усі операції POP. Наскільки ефективно можна повернути список елементів за допомогою двох спочатку порожніх черг? Юридичні операції:O(1)N

  1. Запишіть наступний елемент із списку введення (до хвоста будь-якої черги).
  2. Видаліть елемент на чолі будь-якої черги та знову заставте його (до хвоста будь-якої черги).
  3. Видаліть елемент на чолі будь-якої черги та додайте його до списку вихідних даних.

Якщо вхідний список складається з елементів , то як складається мінімальна кількість операцій, необхідних для генерування списку зворотного виходу поводитись? Доказ того, що він росте швидше, ніж був би особливо цікавим, оскільки він вирішив би початкове питання негативно.[1,2,...,N1,N][N,N1,...,2,1]O(N)


Оновлення (15 січня 2011 р.): Проблему можна вирішити в , як показано у поданих відповідях та їх коментарях; а нижня межа тривіальна. Чи можна покращити будь-який з цих меж?O(NlogN)Ω(N)


Для уточнення: під "останнім елементом з будь-якої черги" ви посилаєтесь на елемент на чолі черги?
Пітер Тейлор

@Peter: Так, дякую за пояснення. Я редагував питання.
mjqxxxx

Чи є стеки списків вводу та виводу? Якщо так, n op1s (до тієї ж черги), за якими n op3s, робить зворотний шлях, правда? Я думаю, що я повинен пропустити щось важливе.
jbapple

@jbapple: Ні, це не стеки. Елементи потрібно записати у вихідний список у тому зворотному порядку, як вони були прочитані зі списку вхідних даних.
mjqxxxx

Відповіді:


11

Якщо N - потужність двох, я вважаю, що операцій O (N log N) достатньо навіть для дещо більш обмеженої проблеми, коли всі елементи починаються на одній з черг і повинні закінчуватися в зворотному порядку на одній із черг (без списки введення та виведення).

На етапах O (N) можна почати з усіх елементів однієї черги, відтворити "один для тебе один для мене", щоб розділити їх на чергування підмножини на іншій черзі, а потім об'єднати їх назад в одну чергу. З точки зору двійкових уявлень позицій елементів, це реалізує операцію обертання.

На етапах O (N) також можна витягнути пари елементів з однієї черги, поміняти їх місцями, а потім поставити їх назад, перевернувши всі пари. Що стосується двійкових уявлень позицій елементів, це доповнює біт позиції низького порядку.

Повторюючи O (log N) разів непереміщення та попарний своп, ми можемо доповнити всі біти двійкових уявлень позицій - це те саме, що перевернути список.


Тоді ви можете розбити список на бінарне подання та реверсувати по частинах для алгоритму O (n lg n).
jbapple

Я думав, що можна поширитись на всі N, використовуючи 2-3 дерева замість двійкових, але, можливо, ваша ідея простіша. Але як повернути кожну з частин O (log n) у загальних кроках O (n log n)?
Девід Еппштейн

Час дорівнює O (сума (2 ^ i) lg (2 ^ i)) для i від 0 до [lg n], про який говорить альфа Вольфрам - O (n lg n): wolframalpha.com/input/?i=sum+ (2 ^ k) + log2 + (2 ^ k) + від + 0 + до + log2 + n
jbapple

Звичайно, якщо ви зможете перевернути кожну частину в часі, пропорційній її довжині, кратній її журналу, ви закінчили. Але ви повинні помістити шматки кудись, коли ви їх перевернули, і це може ускладнити перевернення решти фрагментів.
Девід Еппштейн

Проблема створює "вихідний список". Чи можемо ми їх помістити туди?
jbapple

1

Найкращий алгоритм, який я можу придумати, вимагає переходів з однієї черги на іншу.i=0N/21(N2i2)

Дозволяє назвати дві наявні черги як ліву, так і праву. Ось основна ідея цього алгоритму з припущенням, що N парне:

  1. Прочитайте значення з початкового списку елементів і натисніть усі непарні числа в ліву чергу, а парні числа - у праву чергу
  2. Одним із перших кроків найшвидшого способу вивести максимальне значення - перенести N / 2-1 елементи з правої черги в ліву і вивести верхнє значення з правої черги у список виводу
  3. Тепер ми повинні зробити те ж саме для іншої черги - перенести N / 2-1 елементів з лівої черги в праву і вивести верхній елемент з лівої черги у вихідний список
  4. Поміняйте черги та повторіть кроки 2 та 3 для N = N-2

Неважко зрозуміти, як алгоритм повинен працювати для непарних N.


Ви можете використовувати $ ... $, щоб вставити код LaTeX-ish (мінус \).
Марк Рейтблат
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.