LeetCode Solutions (161 серия деталей)
Это является частью серии объяснений решения LeetCode ( index ). Если вам понравилось это решение или нашли его полезным, Пожалуйста, нравится Этот пост и/или upvote Мое решение по сообщению на форумах LeetCode Анкет
Проблема LeetCode #97 (средняя): Червейная строка
Описание:
( прыгнуть в : Идея решения Код : JavaScript | Python | Java | C ++
Данные строки S1
, S2
и S3
, обнаружил, что S3
формируется Чередование из S1
и S2
Анкет
А Чередование двух строк s
и t
это конфигурация, где они разделены на непусты подстроки такие, что:
-
s + s2 + ... + sn
-
T + T2 + ... + TM
-
| n - m |
- Чередование – это
S1 + T1 + S2 + T2 + S3 + T3 + ...
илиT1 + S1 + T2 + S2 + T3 + S3 + ...
Примечание : a + b
Согласование струн A
и b
Анкет
Примеры:
Вход: | |
Выход: | истинный |
Визуальный: |
Вход: | |
Выход: | ЛОЖЬ |
Вход: | |
Выход: | истинный |
Ограничения:
0.length, s2.length
0.length
S1
,S2
иS3
состоят из строчных английских букв.
Идея:
( Прыгните к : Описание задачи Код : JavaScript | Python | Java | C ++
Если мы рассмотрим матрицу с индексами ( i ) для S1 На одной оси и индексах ( J ) для S2 С другой стороны, тогда успешный S3 можно считать пути, движущейся сверху слева в нижней части справа. В каждой точке мы либо двигаемся вниз ( i ++ ), выбрав следующую букву из S1 или вправо ( J ++ ), выбрав следующую букву из S2 Анкет
Таким образом, все, что остается, – это увидеть, какие вершины возможны S3 , а какие нет. Для этого мы можем использовать динамическое программирование ( dp ) Подход. Обычно мы установили матрицу, как описано выше, наряду с буферной строкой/столбцом в начале матрицы, чтобы обеспечить место для предыдущих проверок проверки строки/столбца для ведущих ребра нашей итерации. Также необходима дополнительная строка/столбец в конце матрицы, поскольку наши последние проверки будут происходить только после Строки завершены.
Мы можем уменьшить Сложность пространства этого решения от O (n * m) только O (м) Однако, если, а не создавать полную матрицу DP, мы вместо этого сохраняем только текущие ряды матрицы ( dp ) в памяти, повторяя ее для каждой строки. Левое значение уже будет рассчитано, и значение UP еще не будет перезаписано в текущей ячейке.
Мы также должны помнить, чтобы заполнить DP [1] с помощью Верно (или 1 ) Значение, представляющее действительную вершину в начальной позиции нашего пути итерации.
Оттуда мы можем перевернуть через ряды, построившись на ранее завершенных записях, чтобы проверить обоснованность текущей ячейки. Если ячейка «выше» (еще не писательный DP [i] представляет тот же индекс из строки выше) действительна ( Верно или 1 ) и соответствующие символы S1 и S3 Совместите, тогда текущая ячейка действительна. Точно так же, если ячейка слева действительна и соответствующие символы S2 а также S3 Совместите, тогда текущая ячейка действительна.
Как только мы закончили итерацию через i и J , допустимое значение в последней ячейке DP укажет, что существует допустимый путь, который соответствует S3 , так что мы можем просто возврат содержимое этой ячейки.
- Сложность времени: O (n * m) куда N является длиной S1 а также M является длиной с2
- Сложность пространства: O (M) за дп
Код JavaScript:
( Прыгните к : Описание задачи Идея решения
var isInterleave = function(s1, s2, s3) { let n = s1.length + 2, m = s2.length + 2 if (n + m - 4 !== s3.length) return false let dp = new Uint8Array(m) dp[1] = 1 for (let i = 1; i < n; i++) for (let j = 1; j < m; j++) { let up = dp[j] && s1[i-2] === s3[j+i-3], left = dp[j-1] && s2[j-2] === s3[j+i-3] dp[j] = up || left } return dp[m-1] };
Код Python:
( Прыгните к : Описание задачи Идея решения
class Solution: def isInterleave(self, s1: str, s2: str, s3: str) -> bool: n, m = len(s1) + 2, len(s2) + 2 if n + m - 4 != len(s3): return False dp = [0] * m dp[1] = 1 for i in range(1, n): for j in range(1, m): up = dp[j] and (i < 2 or s1[i-2] == s3[j+i-3]) left = dp[j-1] and (j < 2 or s2[j-2] == s3[j+i-3]) dp[j] = up or left return dp[-1]
Код Java:
( Прыгните к : Описание задачи Идея решения
class Solution { public boolean isInterleave(String s1, String s2, String s3) { int n = s1.length() + 2, m = s2.length() + 2; char[] sc1 = s1.toCharArray(), sc2 = s2.toCharArray(), sc3 = s3.toCharArray(); if (n + m - 4 != s3.length()) return false; boolean[] dp = new boolean[m]; dp[1] = true; for (int i = 1; i < n; i++) for (int j = 1; j < m; j++) { boolean up = dp[j] && (i < 2 || sc1[i-2] == sc3[j+i-3]), left =dp[j-1] && (j < 2 || sc2[j-2] == sc3[j+i-3]); dp[j] = up || left; } return dp[m-1]; } }
C ++ Код:
( Прыгните к : Описание задачи Идея решения
class Solution { public: bool isInterleave(string s1, string s2, string s3) { int n = s1.length() + 2, m = s2.length() + 2; if (n + m - 4 != s3.length()) return false; vectordp(m); dp[1] = true; for (int i = 1; i < n; i++) for (int j = 1; j < m; j++) { bool up = dp[j] && (i < 2 || s1[i-2] == s3[j+i-3]), left = dp[j-1] && (j < 2 || s2[j-2] == s3[j+i-3]); dp[j] = up || left; } return dp[m-1]; } };
LeetCode Solutions (161 серия деталей)
Оригинал: “https://dev.to/seanpgallivan/solution-interleaving-string-1497”