У меня вопрос: нужна минимальная длина k, чтобы в каждой последовательной подстроке строки длиной k должен был быть хотя бы один общий символ.
например, если s="abcaca"
для k = 1 -> подстроки — это [a], [b], [c] и т. д., поэтому мы не можем найти общий символ во всех. for k = 2 --> [ab], [bc], [ca] ... что снова нет общего символа во всех
но для k = 3 мы имеем [abc], [bca], [cac] [aca], что a и c присутствуют во всех подстроках, поэтому ответ — k.
или для s="abc" мы имеем k=2, как описано выше. мой код работает правильно, но он не оптимален для большой длины s. может ли кто-нибудь решить эту проблему с помощью динамического скользящего окна или других оптимальных способов?
n = input()
queue = list(n)
k = 1
s1 = 0
s2 = 1
last_intersection = None
sub_1 = set(queue[0:1])
while (s2 + k) < len(queue) + 1:
sub_2 = set(queue[s2: s2 + k])
if len(sub_2.intersection(sub_1)) > 0:
sub_1 = sub_2.intersection(sub_1)
s2 += 1
else:
s1 = 0
s2 = 1
k += 1
sub_1 = set(queue[s1: s1 + k])
print(k)
мы должны проверять k от 1 до тех пор, пока не дойдем до конца строки или когда у нас есть подстрока длиной k, последний символ которой является последним символом строки: например, в s = "abc" мы можем иметь 3 последовательная подстрока с k=1: 'a', 'b', 'c', и у нас может быть 2 подстроки с k=2: 'ab', 'bc', мы также можем иметь k=3, но наименьшее k, которое удовлетворяет условие задачи — k=2, потому что мы можем найти символ («b») во всех последовательных подстроках длины 2, которые можем.
Какие ограничения? Длина строки, размер алфавита?
@MBo просто размер строки от 1 до 100 000





Вот логика:
s = "abcaca"
k = 1
n = len(s) # length of string s
while k < n:
a = set(s[:k])
for i in range(n - k + 1):
a &= set(s[i:i+k]) # intersection
if not a: break #if intersection is empty, no need to continue.
if a: break #if after traversing the string, intersection is not empty, break
k += 1
print(k)
3
ответ правильный, но все же я указываю превышение лимита времени для больших строк.
@AmirHossein, какова длина твоей строки?
длина от 1 до 100000
Мы можем использовать бинарный поиск для повышения эффективности:
def solve(s):
def find(k):
A = set(s[:k])
for i in range(1, n - k + 1):
A &= set(s[i:i + k])
if len(A) == 0:
return False
return True
n = len(s)
lo, hi = 1, len(s)
while lo <= hi:
mid = (lo + hi) // 2
if find(mid):
hi = mid - 1
else:
lo = mid + 1
return lo
print(solve("abcaca")) # [abc], [bca], [cac] [aca]
print(solve("abc"))
print(solve("abcacaabcdabcdeabcdeabcde"))
3
2
5
Не думайте, что эта функция поддерживает двоичный поиск.
ответ правильный, но все же я указываю превышение лимита времени для больших строк. есть ли другой способ уменьшить временную сложность?
Чтобы все подстроки содержали a, длина подстроки должна равняться максимальному расстоянию между отдельными a. То же самое для b, c и т. д.
Итак, для каждого символа алфавита найдите максимальное расстояние между его вхождениями и выберите минимальное из них. Вычисление максимальных расстояний можно выполнить за один проход по строке, а выбор минимального — за один проход по алфавиту.
Рассмотрим s = "bbaaac", правильное k равно 3, как ваш ответ может решить эту проблему?
Не забывайте о вступлении и завершении. Чтобы a появился в самой первой подстроке, она должна иметь длину 3: bba. Чтобы b появился в самой последней подстроке, она должна иметь длину 5: baaac.
я знаю, но как насчет б?? Максимальное расстояние для b равно 1, а отведение тоже равно 1, поэтому минимальное расстояние между 1, 3 и 5 равно 1, но правильный ответ – 3, или в s = ""aaab" для расстояния равно 1, а для b равно 4. , но правильный ответ 2
Не забывайте о выводе. Для b в первой строке это 4, а для a во второй — 2.
Эту проблему можно решить за линейное время по длине строки, найдя минимальное из всех максимальных расстояний между ближайшими вхождениями одного и того же символа (как также описано user58697).
Вот реализация:
def solve(s: str) -> int:
prev_idx, max_dist = {}, {}
for i, c in enumerate(s):
max_dist[c], prev_idx[c] = max(max_dist.get(c, 0), i - prev_idx.get(c, -1)), i
return min(max(d, len(s) - prev_idx[c]) for c, d in max_dist.items())
print(solve("abcaca")) # 3
print(solve("abc")) # 2
print(solve("bbaaac")) # 3
print(solve("aaab")) # 2
Спасибо, это работает в линейном времени и решает мою проблему.
@AmirHossein Рад помочь.
k может быть любым числом, и нам нужно найти минимальное значение k, при котором у нас есть общий символ в последовательных подстроках длиной k. не имеет значения, кратна ли длина строки k или нет.