Минимальный символ, который необходимо удалить

Оригинальная проблема:

Слово было K-хорошим, если для каждые две буквы в слове, если первый появляется x раз, а второй появляется y раз, тогда |x - y| ≤ K.

Учитывая некоторое слово w, сколько букв он должен удалить, чтобы сделать его K-хорошим?
Ссылка на проблему.

Я решил эту проблему и не просил решения для вышеперечисленного Проблема

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



Проблема модификации

Слово было K-хорошим, если для каждого двух последовательных букв в слове, если первый появляется x раз, а второй появляется y раз, тогда |x - y| ≤ K.

Учитывая некоторое слово w, сколько букв ему нужно удалить, чтобы сделать его K-хорошим?

Является ли эта проблема разрешимой в линейном времени, я подумал об этом, но не нашел подходящего решения.

Решение

Мой подход: я не мог подойти к моей давке, но она - мой подход к этой проблеме, попробуйте все (из фильма Zooptopia)

то есть.

for i range(0,1<<n):   // n length of string
    for j in range(0,n):
          if(i&(1<<j) is not zero): delete the character
   Now check if String is K good 

Для N в диапазоне 10^5. Сложность времени: времени в этом измерении не существует.

Есть ли линейное решение этой проблемы, простое и приятное, как люди stackoverflow.

For Ex:
String S = AABCBBCB and K=1


   If we delete 'B' at index 5 so String S = AABCBCB which is good string
    F[A]-F[A]=0
    F[B]-F[A]=1
    F[C]-F[B]=1
    and so on

Я думаю, что это простой пример, я могу более сложный пример как удаление I-элемента makens (I-1) и (I + 1) в качестве последовательного

Ответы

Ответ 1

Существует ли линейное решение этой проблемы?

Рассмотрим слово DDDAAABBDC. Это слово является 3-хорошим, потому что D и C являются последовательными и card(D)-card(C)=3, а удаление последнего D делает его 1-хорошим, делая D и C не последовательными.

И наоборот, если я считаю DABABABBDC, который является 2-хорошим, удаление последнего D делает C и B последовательным и увеличивает значение K слова до 3.

Это означает, что в модифицированной задаче значение K слова определяется как кардиналами каждой буквы, так и кардиналами каждой пары последовательных букв.

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

Также важно заметить, что если в исходной задаче все буквы эквивалентны (я могу удалить их безразлично), а в измененной задаче это уже не так.

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

Ответ 2

Вместо поиска линейного решения времени, которое, как я думаю, не существует (в том числе потому, что, как представляется, существует множество альтернативных решений для каждого запроса K), я бы хотел установить решение полностью geeky.

А именно, возьмите язык обработки параллельного массива Dyalog APL и создайте эти две крошечные динамические функции:

good←{1≥⍴⍵:¯1 ⋄ b←(⌈/a←(∪⍵)⍳⍵)⍴0 ⋄ b[a]+←1 ⋄ ⌈/|2-/b[a]}

make←{⍵,(good ⍵),a,⍺,(l-⍴a←⊃b),⍴b←(⍺=good¨b/¨⊂⍵)⌿(b←↓⍉~(l⍴2)⊤0,⍳2⊥(l←⍴⍵)⍴1)/¨⊂⍵}

good сообщает нам K-доброту строки. Несколько примеров ниже:

// fn" means the fn executes on each of the right args
good" 'AABCBBCB' 'DDDAAABBDC' 'DDDAAABBC' 'DABABABBDC' 'DABABABBC' 'STACKOVERFLOW'
2 3 1 2 3 1

make принимает в качестве аргументов

[desired K] make [any string]

и возвращает  - оригинальная строка
 - K для оригинальной строки
 - уменьшенная строка для желаемого K
 - сколько персонажей было удалено для достижения  - сколько возможных решений для достижения желаемого K

Например:

3 make 'DABABABBDC'
┌──────────┬─┬─────────┬─┬─┬──┐
│DABABABBDC│2│DABABABBC│3│1│46│
└──────────┴─┴─────────┴─┴─┴──┘

Немного длиннее строка:

 1 make 'ABCACDAAFABBC'
┌─────────────┬─┬────────┬─┬─┬────┐
│ABCACDAAFABBC│4│ABCACDFB│1│5│3031│
└─────────────┴─┴────────┴─┴─┴────┘

Можно увеличивать и уменьшать K-доброту.

К сожалению, это грубая сила. Мы генерируем 2-базу всех целых чисел между 2 ^ [длина строки] и 1, например:

0 1 0 1 1

Затем мы проверяем доброту подстроки, например:

0 1 0 1 1 / 'STACK'  // Substring is now 'TCK'

Мы выбираем только те результаты (подстроки), которые соответствуют желаемому K-хорошему. Наконец, из множества возможных результатов мы выбираем первый, который остается с большинством оставшихся символов.

По крайней мере, это было забавно для кода: -).