Программа курса:
Разбор задачи: Поиск и замена шаблона
Предложенный нами код:
def findAndReplacePattern(words, pattern):
"""
:type words: List[str]
:type pattern: str
:rtype: List[str]
"""
res = []
for w in words:
mp12, mp21, match = {}, {}, True
for c1, c2 in zip(w, pattern):
if (c1 in mp12 and mp12[c1] != c2) or (c2 in mp21 and mp21[c2] != c1):
match = False
break
mp12[c1], mp21[c2] = c2, c1
if match: res.append(w)
return resДавайте разберем решение задачи на примере вашего кода. В этом решении функция findAndReplacePattern проверяет, какие слова из списка соответствуют заданному паттерну, где существует взаимно однозначное соответствие между буквами в словах и паттерне.
Основная идея:
Необходимо найти слова, которые могут быть преобразованы в паттерн с помощью перестановки букв. Важно, чтобы каждая буква в слове соответствовала своей уникальной букве в паттерне, и наоборот, каждая буква в паттерне соответствовала своей уникальной букве в слове.
Шаги выполнения:
1. Инициализация пустого списка:
res = []
Мы начинаем с пустого списка res, в который будем добавлять все слова, соответствующие паттерну.
2. Перебор всех слов из списка:
for w in words:
Мы перебираем каждое слово из списка words. Для каждого слова будем проверять, может ли оно быть преобразовано в паттерн.
3. Для каждого слова создаем два словаря:
mp12, mp21, match = {}, {}, True
mp12: будет хранить соответствие букв из слова в буквы из паттерна (слева направо).mp21: будет хранить соответствие букв из паттерна в буквы из слова.match: флаг, который изначально устанавливается вTrueи будет менять свое значение наFalse, если на каком-то шаге перестановка не будет выполнена корректно.
4. Перебор символов в слове и паттерне:
for c1, c2 in zip(w, pattern):
Используем zip, чтобы одновременно перебирать символы из слова w и паттерна pattern. В каждой итерации переменные c1 и c2 будут хранить текущие символы из слова и паттерна соответственно.
5. Проверка соответствия букв:
if (c1 in mp12 and mp12[c1] != c2) or (c2 in mp21 and mp21[c2] != c1):
match = False
break
В этом фрагменте мы проверяем два условия:
- Если символ
c1уже был сопоставлен с другим символом в паттерне (по записи вmp12), то проверяем, соответствует ли он текущему символуc2. Если не соответствует, устанавливаемmatch = Falseи выходим из цикла, потому что дальнейшее сопоставление бессмысленно. - Аналогично проверяем символы в другом направлении: если символ
c2в паттерне уже был связан с другим символом из слова, то это несоответствие также приведет к установкеmatch = False.
6. Заполнение словарей:
mp12[c1], mp21[c2] = c2, c1
Если символы соответствуют друг другу, добавляем их в словари:
mp12[c1] = c2— это означает, что символc1из слова соответствует символуc2из паттерна.mp21[c2] = c1— это означает, что символc2из паттерна соответствует символуc1из слова.
7. Добавление слова в результат:
if match:
res.append(w)
Если после проверки всех символов из слова и паттерна флаг match остался равным True, то это означает, что слово успешно соответствует паттерну, и мы добавляем его в список res.
8. Возвращение результата:
return res
Возвращаем список слов, которые соответствуют паттерну.
Пример 1:
words = ["abc", "deq", "mee", "aqq", "dkd", "ccc"]
pattern = "abb"
- Для слова "abc" не существует корректной перестановки для "abb", потому что "a" не может быть связано с двумя разными буквами "b".
- Для слова "mee" можно провести перестановку: "m" -> "a", "e" -> "b", и получится слово "mee", которое соответствует паттерну "abb".
- Аналогично для слова "aqq".
- Результат:
["mee", "aqq"].
Пример 2:
words = ["a", "b", "c"]
pattern = "a"
- Все слова состоят из одного символа, и каждый символ из паттерна может быть сопоставлен с любым из этих символов. Результат:
["a", "b", "c"].