Учитывая только один палиндром, вам придется сделать это за O (N), да. Вы можете добиться большей эффективности с несколькими процессорами, разделив строку, как вы сказали.
Теперь скажите, что хотите точно сопоставить ДНК. Эти строки длиной в тысячи символов, и они очень повторяются. Это дает нам возможность оптимизировать.
Допустим, вы разбили строку длиной 1000 символов на 5 пар по 100 100. Код будет выглядеть так:
isPal(w[0:100],w[-100:]) and isPail(w[101:200], w[-200:-100]) ...
и т. Д. В первый раз, когда вы делаете эти совпадения, вам нужно будет их обработать. Тем не менее, вы можете добавить все результаты, которые вы сделали, в пары сопоставления хеш-таблицы для логических значений:
isPal = {("ATTAGC", "CGATTA"): True, ("ATTGCA", "CAGTAA"): False}
и т.д ... это займет слишком много памяти. Для пар 100,100 хэш-карта будет иметь 2 * 4 ^ 100 элементов. Скажем, вы храните в качестве ключа только два 32-битных хэша строк, вам потребуется что-то вроде 10 ^ 55 мегабайт, что смешно.
Может быть, если вы используете меньшие строки, проблема может быть устранена. Тогда у вас будет огромная хэш-карта, но, по крайней мере, палиндром, скажем, для пар 10x10 потребуется O (1), поэтому для проверки, является ли строка 1000 палиндромом, потребуется 100 поисков вместо 500 сравнений. Это все еще O (N), хотя ...