bool isInterleave(string s1, string s2, string s3) {
if (s1.size() + s2.size() != s3.size()) return false;
function<bool(int, int)> rec = [&](int i, int j) -> bool {
if (i == (int)s1.size() && j == (int)s2.size()) return true;
char c = s3[i + j];
if (i < (int)s1.size() && s1[i] == c && rec(i + 1, j)) return true;
if (j < (int)s2.size() && s2[j] == c && rec(i, j + 1)) return true;
return false;
};
return rec(0, 0);
}
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.length() + s2.length() != s3.length()) return false;
return rec(s1, s2, s3, 0, 0);
}
private boolean rec(String s1, String s2, String s3, int i, int j) {
if (i == s1.length() && j == s2.length()) return true;
char c = s3.charAt(i + j);
if (i < s1.length() && s1.charAt(i) == c && rec(s1, s2, s3, i + 1, j)) return true;
if (j < s2.length() && s2.charAt(j) == c && rec(s1, s2, s3, i, j + 1)) return true;
return false;
}
def is_interleave(s1, s2, s3):
if len(s1) + len(s2) != len(s3): return False
def rec(i, j):
if i == len(s1) and j == len(s2): return True
c = s3[i + j]
if i < len(s1) and s1[i] == c and rec(i + 1, j): return True
if j < len(s2) and s2[j] == c and rec(i, j + 1): return True
return False
return rec(0, 0)
function isInterleave(s1: string, s2: string, s3: string): boolean {
if (s1.length + s2.length !== s3.length) return false;
const rec = (i: number, j: number): boolean => {
if (i === s1.length && j === s2.length) return true;
const c = s3[i + j];
if (i < s1.length && s1[i] === c && rec(i + 1, j)) return true;
if (j < s2.length && s2[j] === c && rec(i, j + 1)) return true;
return false;
};
return rec(0, 0);
}
bool isInterleave(string s1, string s2, string s3) {
if (s1.size() + s2.size() != s3.size()) return false;
unordered_map<int, bool> memo;
function<bool(int, int)> rec = [&](int i, int j) -> bool {
if (i == (int)s1.size() && j == (int)s2.size()) return true;
int key = i * ((int)s2.size() + 1) + j;
auto it = memo.find(key);
if (it != memo.end()) return it->second;
char c = s3[i + j];
bool ok = (i < (int)s1.size() && s1[i] == c && rec(i + 1, j)) || (j < (int)s2.size() && s2[j] == c && rec(i, j + 1));
memo[key] = ok;
return ok;
};
return rec(0, 0);
}
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.length() + s2.length() != s3.length()) return false;
Map<Integer, Boolean> memo = new HashMap<>();
return rec(s1, s2, s3, 0, 0, memo);
}
private boolean rec(String s1, String s2, String s3, int i, int j, Map<Integer, Boolean> memo) {
if (i == s1.length() && j == s2.length()) return true;
int key = i * (s2.length() + 1) + j;
if (memo.containsKey(key)) return memo.get(key);
char c = s3.charAt(i + j);
boolean ok = (i < s1.length() && s1.charAt(i) == c && rec(s1, s2, s3, i + 1, j, memo)) || (j < s2.length() && s2.charAt(j) == c && rec(s1, s2, s3, i, j + 1, memo));
memo.put(key, ok);
return ok;
}
def is_interleave(s1, s2, s3):
if len(s1) + len(s2) != len(s3): return False
memo = {}
def rec(i, j):
if i == len(s1) and j == len(s2): return True
key = i * (len(s2) + 1) + j
if key in memo: return memo[key]
c = s3[i + j]
ok = (i < len(s1) and s1[i] == c and rec(i + 1, j)) or (j < len(s2) and s2[j] == c and rec(i, j + 1))
memo[key] = ok
return ok
return rec(0, 0)
function isInterleave(s1: string, s2: string, s3: string): boolean {
if (s1.length + s2.length !== s3.length) return false;
const memo = new Map<number, boolean>();
const rec = (i: number, j: number): boolean => {
if (i === s1.length && j === s2.length) return true;
const key = i * (s2.length + 1) + j;
if (memo.has(key)) return memo.get(key)!;
const c = s3[i + j];
const ok = (i < s1.length && s1[i] === c && rec(i + 1, j)) || (j < s2.length && s2[j] === c && rec(i, j + 1));
memo.set(key, ok);
return ok;
};
return rec(0, 0);
}
bool isInterleave(string s1, string s2, string s3) {
int m = s1.size(), n = s2.size();
if (m + n != (int)s3.size()) return false;
vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
dp[m][n] = true;
for (int i = m; i >= 0; i--) {
for (int j = n; j >= 0; j--) {
if (i == m && j == n) continue;
char c = s3[i + j];
dp[i][j] = (i < m && s1[i] == c && dp[i + 1][j]) || (j < n && s2[j] == c && dp[i][j + 1]);
}
}
return dp[0][0];
}
public boolean isInterleave(String s1, String s2, String s3) {
int m = s1.length(), n = s2.length();
if (m + n != s3.length()) return false;
boolean[][] dp = new boolean[m + 1][n + 1];
dp[m][n] = true;
for (int i = m; i >= 0; i--) {
for (int j = n; j >= 0; j--) {
if (i == m && j == n) continue;
char c = s3.charAt(i + j);
dp[i][j] = (i < m && s1.charAt(i) == c && dp[i + 1][j]) || (j < n && s2.charAt(j) == c && dp[i][j + 1]);
}
}
return dp[0][0];
}
def is_interleave(s1, s2, s3):
m, n = len(s1), len(s2)
if m + n != len(s3): return False
dp = [[False] * (n + 1) for _ in range(m + 1)]
dp[m][n] = True
for i in range(m, -1, -1):
for j in range(n, -1, -1):
if i == m and j == n: continue
c = s3[i + j]
dp[i][j] = (i < m and s1[i] == c and dp[i + 1][j]) or (j < n and s2[j] == c and dp[i][j + 1])
return dp[0][0]
function isInterleave(s1: string, s2: string, s3: string): boolean {
const m = s1.length, n = s2.length;
if (m + n !== s3.length) return false;
const dp = Array.from({ length: m + 1 }, () => new Array<boolean>(n + 1).fill(false));
dp[m][n] = true;
for (let i = m; i >= 0; i--) {
for (let j = n; j >= 0; j--) {
if (i === m && j === n) continue;
const c = s3[i + j];
dp[i][j] = (i < m && s1[i] === c && dp[i + 1][j]) || (j < n && s2[j] === c && dp[i][j + 1]);
}
}
return dp[0][0];
}
bool isInterleave(string s1, string s2, string s3) {
if (s1.size() + s2.size() != s3.size()) return false;
if (s1.size() < s2.size()) swap(s1, s2);
int m = s1.size(), n = s2.size();
vector<char> row(n + 1, 0);
row[n] = 1;
for (int i = m; i >= 0; i--) {
for (int j = n; j >= 0; j--) {
if (i == m && j == n) continue;
char c = s3[i + j];
row[j] = (i < m && s1[i] == c && row[j]) || (j < n && s2[j] == c && row[j + 1]);
}
}
return row[0];
}
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.length() + s2.length() != s3.length()) return false;
if (s1.length() < s2.length()) { String t = s1; s1 = s2; s2 = t; }
int m = s1.length(), n = s2.length();
boolean[] row = new boolean[n + 1];
row[n] = true;
for (int i = m; i >= 0; i--) {
for (int j = n; j >= 0; j--) {
if (i == m && j == n) continue;
char c = s3.charAt(i + j);
row[j] = (i < m && s1.charAt(i) == c && row[j]) || (j < n && s2.charAt(j) == c && row[j + 1]);
}
}
return row[0];
}
def is_interleave(s1, s2, s3):
if len(s1) + len(s2) != len(s3): return False
if len(s1) < len(s2): s1, s2 = s2, s1
m, n = len(s1), len(s2)
row = [False] * (n + 1)
row[n] = True
for i in range(m, -1, -1):
for j in range(n, -1, -1):
if i == m and j == n: continue
c = s3[i + j]
row[j] = (i < m and s1[i] == c and row[j]) or (j < n and s2[j] == c and row[j + 1])
return row[0]
function isInterleave(s1: string, s2: string, s3: string): boolean {
if (s1.length + s2.length !== s3.length) return false;
if (s1.length < s2.length) [s1, s2] = [s2, s1];
const m = s1.length, n = s2.length;
const row = new Array<boolean>(n + 1).fill(false);
row[n] = true;
for (let i = m; i >= 0; i--) {
for (let j = n; j >= 0; j--) {
if (i === m && j === n) continue;
const c = s3[i + j];
row[j] = (i < m && s1[i] === c && row[j]) || (j < n && s2[j] === c && row[j + 1]);
}
}
return row[0];
}