97. Interleaving String

Medium

Problem Description

Given strings s1, s2, and s3, find whether s3 is formed by an interleaving of s1 and s2.

An interleaving of two strings s and t is a configuration where s and t are divided into n and m substrings respectively, such that:

Note: a + b is the concatenation of strings a and b.

Examples

Example 1:
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true
Explanation: One way to obtain s3 is:
Split s1 into s1 = "aa" + "bc" + "c"
Split s2 into s2 = "dbbc" + "a"
Interleaving the two splits: "aa" + "dbbc" + "bc" + "a" + "c" = "aadbbcbcac"

Example 2:
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
Output: false
Explanation: Notice how it is impossible to interleave s2 with any other string to obtain s3.

Example 3:
Input: s1 = "", s2 = "", s3 = ""
Output: true
Jump to Solution: Python Java C++ JavaScript C#

Python Solution


def isInterleave(s1: str, s2: str, s3: str) -> bool:
    if len(s1) + len(s2) != len(s3):
        return False
    
    # dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
    dp = [[False] * (len(s2) + 1) for _ in range(len(s1) + 1)]
    dp[0][0] = True
    
    # Initialize first row
    for j in range(1, len(s2) + 1):
        dp[0][j] = dp[0][j-1] and s2[j-1] == s3[j-1]
    
    # Initialize first column
    for i in range(1, len(s1) + 1):
        dp[i][0] = dp[i-1][0] and s1[i-1] == s3[i-1]
    
    # Fill the dp table
    for i in range(1, len(s1) + 1):
        for j in range(1, len(s2) + 1):
            dp[i][j] = (dp[i-1][j] and s1[i-1] == s3[i+j-1]) or \
                      (dp[i][j-1] and s2[j-1] == s3[i+j-1])
    
    return dp[len(s1)][len(s2)]

Java Solution


class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        if (s1.length() + s2.length() != s3.length()) {
            return false;
        }
        
        // dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
        boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
        dp[0][0] = true;
        
        // Initialize first row
        for (int j = 1; j <= s2.length(); j++) {
            dp[0][j] = dp[0][j-1] && s2.charAt(j-1) == s3.charAt(j-1);
        }
        
        // Initialize first column
        for (int i = 1; i <= s1.length(); i++) {
            dp[i][0] = dp[i-1][0] && s1.charAt(i-1) == s3.charAt(i-1);
        }
        
        // Fill the dp table
        for (int i = 1; i <= s1.length(); i++) {
            for (int j = 1; j <= s2.length(); j++) {
                dp[i][j] = (dp[i-1][j] && s1.charAt(i-1) == s3.charAt(i+j-1)) ||
                          (dp[i][j-1] && s2.charAt(j-1) == s3.charAt(i+j-1));
            }
        }
        
        return dp[s1.length()][s2.length()];
    }
}

C++ Solution


class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        if (s1.length() + s2.length() != s3.length()) {
            return false;
        }
        
        // dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
        vector> dp(s1.length() + 1, vector(s2.length() + 1, false));
        dp[0][0] = true;
        
        // Initialize first row
        for (int j = 1; j <= s2.length(); j++) {
            dp[0][j] = dp[0][j-1] && s2[j-1] == s3[j-1];
        }
        
        // Initialize first column
        for (int i = 1; i <= s1.length(); i++) {
            dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1];
        }
        
        // Fill the dp table
        for (int i = 1; i <= s1.length(); i++) {
            for (int j = 1; j <= s2.length(); j++) {
                dp[i][j] = (dp[i-1][j] && s1[i-1] == s3[i+j-1]) ||
                          (dp[i][j-1] && s2[j-1] == s3[i+j-1]);
            }
        }
        
        return dp[s1.length()][s2.length()];
    }
};

JavaScript Solution


/**
 * @param {string} s1
 * @param {string} s2
 * @param {string} s3
 * @return {boolean}
 */
var isInterleave = function(s1, s2, s3) {
    if (s1.length + s2.length !== s3.length) {
        return false;
    }
    
    // dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
    const dp = Array(s1.length + 1).fill().map(() => Array(s2.length + 1).fill(false));
    dp[0][0] = true;
    
    // Initialize first row
    for (let j = 1; j <= s2.length; j++) {
        dp[0][j] = dp[0][j-1] && s2[j-1] === s3[j-1];
    }
    
    // Initialize first column
    for (let i = 1; i <= s1.length; i++) {
        dp[i][0] = dp[i-1][0] && s1[i-1] === s3[i-1];
    }
    
    // Fill the dp table
    for (let i = 1; i <= s1.length; i++) {
        for (let j = 1; j <= s2.length; j++) {
            dp[i][j] = (dp[i-1][j] && s1[i-1] === s3[i+j-1]) ||
                      (dp[i][j-1] && s2[j-1] === s3[i+j-1]);
        }
    }
    
    return dp[s1.length][s2.length];
};

C# Solution


public class Solution {
    public bool IsInterleave(string s1, string s2, string s3) {
        if (s1.Length + s2.Length != s3.Length) {
            return false;
        }
        
        // dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
        bool[,] dp = new bool[s1.Length + 1, s2.Length + 1];
        dp[0,0] = true;
        
        // Initialize first row
        for (int j = 1; j <= s2.Length; j++) {
            dp[0,j] = dp[0,j-1] && s2[j-1] == s3[j-1];
        }
        
        // Initialize first column
        for (int i = 1; i <= s1.Length; i++) {
            dp[i,0] = dp[i-1,0] && s1[i-1] == s3[i-1];
        }
        
        // Fill the dp table
        for (int i = 1; i <= s1.Length; i++) {
            for (int j = 1; j <= s2.Length; j++) {
                dp[i,j] = (dp[i-1,j] && s1[i-1] == s3[i+j-1]) ||
                         (dp[i,j-1] && s2[j-1] == s3[i+j-1]);
            }
        }
        
        return dp[s1.Length, s2.Length];
    }
}

Complexity Analysis

Solution Explanation

This solution uses dynamic programming:

Key points: