Хобрук: Ваш путь к мастерству в программировании

Как эффективно переставить символы в строке так, чтобы не было пар?

Имеется строка длиной до 10^5 символов A..Z. Задача состоит в том, чтобы переставить его так, чтобы ни один из символов не образовывал ряд. Для нескольких решений правильным является то, которое идет первым в алфавитном порядке. И это должно быть сделано в разумные сроки, конечно.

Итак, я попробовал два подхода, и один из них перестраивает правильно, но очень неэффективно, а другой, я думаю, нарушил логику.

Медленный подход.

  1. Сортировать массив символов
  2. Перестановка на месте, аналогичная сортировке вставками (поэтому она такая медленная)

Неправильный подход (не всегда дает первый ответ в алфавитном порядке)

  1. Сортировать
  2. Переместите элементы, начиная с конца, в другой массив, сохраняя инвариант
  3. Обратный

Я действительно застрял и не могу думать ни о чем другом здесь.

Примеры:

"HHABC" -> "ABHCH";
"CBAXXXX" -> "XAXBXCX";
"AAABBBCCCCCCCDDDDD" -> "ABABACBCDCDCDCDCDC";

Вот алгоритм решения модели в деталях. Я думаю, что мне не разрешено публиковать фактический код, поэтому он такой:

  1. Постройте гистограмму. Он может храниться в массиве целых чисел, где индексами являются ascii-коды, поэтому сопоставление не требуется.
  2. Build the new string:
    • for each character go alphabetically, from A to Z
    • если по гистограмме такого символа нет, переходим к следующему
    • если предыдущий написанный символ был таким же, перейти к следующему (если это не первая итерация)
    • написать первый найденный подходящий символ
    • уменьшить число на гистограмме
    • если есть (длина-i+2)/2 текущего символа (половина того, что осталось), выйти из этого цикла и перейти к следующему символу в строке.

Это намного короче и проще, чем тот беспорядок, который я написал в конце концов (хотя он работал нормально, и большое спасибо за помощь).


  • Вам действительно не нужно сортировать или переупорядочивать входные данные. Поскольку у вас есть только 26 возможных входных значений, просто сгенерируйте гистограмму за O (n), а затем используйте счетчик ячеек гистограммы для создания выходной последовательности с соответствующим чередованием, снова за O (n). 08.09.2014
  • Я знал, что мое мышление чрезмерно сложно. Но сейчас я не могу ухватиться за эту идею. Как мне сделать вторую часть, если простыми словами? 08.09.2014

Ответы:


1

Хорошо, Пол Р. Если у вас есть гистограмма с количеством вхождений каждого элемента, вы можете отсортировать эти сегменты по количеству вхождений от большего к меньшему. Пока количество вхождений в одной корзине не превышает количество корзин, вы сможете сформировать жизнеспособную строку. Начиная с самых больших сегментов, прокручивайте каждое вхождение в следующем по величине сегменте до меньших сегментов.

Например, AAAABBCRRSTT

AAAAA BB C RR S TT -> AAAAA BB RR TT C S

ABARATACASBRT

08.09.2014
  • Благодарю вас! Я только начал понимать идею за мгновение до того, как прочитал ваш ответ. сейчас пойду попробую. Звучит солидно и просто. 08.09.2014
  • Добро пожаловать! Вам также может понадобиться взглянуть на то, как взять эти корзины и переместить несколько персонажей, чтобы сделать их более одинаковыми по размеру. Таким образом, вы можете избежать коллизий с теми входными символами, которые встречаются довольно часто. 08.09.2014
  • Но на самом деле ответ неверный. Это должно быть ABABACARARTST 08.09.2014
  • А, теперь я понимаю, что вы имеете в виду, говоря, что первое слово в алфавитном порядке является правильным. Вы определенно можете сортировать ведра: AAAAA BB C RR S TT, но вероятность коллизий все же есть. Вы должны сказать, что если длина ведра[i] ‹ ведра[i+1], поменяйте местами ведро. 08.09.2014
  • Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..