Рубрики
Без рубрики

Решение: чередовая строка

Это является частью серии объяснений решений LeetCode (индекс). Если вам понравилось это решение или … с меткой алгоритмы, JavaScript, Java, Python.

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;
        vector dp(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”