Задача с собеседования в

Другое 21.10.2026 · 👁 818 просмотров
Задача с собеседования в eBay Дана строка s, проверьте, можно ли составить её, взяв какую-либо её подстроку и повторив её два или более раз подряд. Пример 1: Input: s = "abab" Output: true Explanation: Это подстрока "ab", повторяющаяся дважды. Пример 2: Input: s = "aba" Output: false Пример 3: Input: s = "abcabcabcabc" Output: true Explanation: Это подстрока "abc", повторяющаяся четыре раза, или подстрока "abcabc", повторяющаяся дважды. Ограничения: 1 <= s.length <= 10⁴ s состоит из строчных английских букв. НАШ ЧАТ АЛГОРИТМИСТОВ Решение Если s состоит из повторяющихся подстрок, то у неё есть длинный собственный префикс, равный её суффиксу. Классический метод решения задачи - префикс-функция из алгоритма Кнута-Морриса-Пратта . Префикс-функция даёт длины наибольших бордеров для всех префиксов. Бордер - собственный префикс строки, являющийся одновременно её суффиксом. Необходимо проверить, образует ли бордер период всей строки. Создаем массив lps (longest prefix-suffix), где lps[i] хранит длину наибольшего собственного префикса подстроки s[0..i], который одновременно является её суффиксом. Если при вычислении префикс-функции символы не совпадают, длина префикса (k) не сбрасывается в ноль, а "откатывается" к уже вычисленному значению для более короткого префикса. Идём по строке слева направо, храня k - длину текущего совпавшего префикса: Пока k > 0 (префикс непустой) и s[i] != s[k] (символы не совпали): - "откатываемся" к наибольшему валидному бордеру меньшей длины: k = lps[k - 1] (если префикс s[0..k-1] равен суффиксу s[i-k..i-1], то любой бордер строки s[0..k-1] также является бордером и для s[0..i-1]. Наибольший такой бордер имеет длину lps[k - 1]). Если s[i] == s[k]: - продлеваем совпавший префикс текущим символом (k += 1). Записываем результат: lps[i] = k. Разберем на примере 1, где s = "abab": - Подстрока "a" (i = 0): собственных префиксов нет => lps[0] = 0. - Подстрока "ab" (i = 1): префикс "a" != суффикс "b" => lps[1] = 0. - Подстрока "aba" (i = 2): префикс "a" == суффикс "a" => lps[2] = 1. - Подстрока "abab" (i = 3): префикс "ab" == суффикс "ab" => lps[3] = 2. Получившийся массив lps: [0, 0, 1, 2] L (длина бордера всей строки) = lps[n - 1]. Если L > 0, то префикс длины L совпадает с суффиксом длины L: s[0..L-1] == s[n-L..n-1]. Суффикс начинается с индекса n - L, т.е. для любого индекса j от 0 до L-1 будет выполняться s[j] == s[j + (n - L)]. Таким образом, строка сдвигается сама на себя с шагом p = n - L. p - кандидат на длину минимального периода. Чтобы строка состояла из точных повторов этого периода, должны выполняться следующие два условия: - L > 0 (иначе p = n и n % n == 0 даст true для любой строки, к примеру, "abcd") - n % p == 0 (общая длина строки должна нацело делиться на длину периода. К примеру, для "ababa", где n = 5, L = 3, p = 2 и 5 % 2 != 0). Сложность O(n) - по времени (k увеличивается не более чем на 1 за каждую итерацию внешнего цикла for, в цикле while - k только уменьшается. Таким образом, суммарное число итераций while не превышает n) O(n) - по памяти (строим массив lps) Код class Solution: def repeatedSubstringPattern(self, s: str) -> bool: n = len(s) lps = [0] * n for i in range(1, n): k = lps[i - 1] while k > 0 and s[i] != s[k]: k = lps[k - 1] if s[i] == s[k]: k += 1 lps[i] = k L = lps[n - 1] p = n - L return L > 0 and n % p == 0 @algoses
Откликнуться в Telegram →

⚠️ Никогда не платите «за оформление» или «гарантию трудоустройства» — это признак мошенников. Работа ТРУ не несёт ответственности за содержание вакансии.

🇮🇱 Не нашли подходящую зарплату? В Израиле платят от $3000 Без языка и опыта · жильё и легализация под ключ · официально Смотреть вакансии →