* Brute Force - DFS
* Time O((N + M) * 2^(N + (M / 2))) | Space O(N^2 + M^2)
* https://leetcode.com/problems/regular-expression-matching/
* @param {string} s
* @param {string} p
* @return {boolean}
*/
var isMatch = (text, pattern) => {
const isBaseCase = pattern.length === 0;
if (isBaseCase) return text.length === 0;
const isTextAndPatternEqual = pattern[0] === text[0],
isPatternPeriod = pattern[0] === '.',
isFirstMatch = text && (isTextAndPatternEqual || isPatternPeriod),
isNextPatternWildCard = pattern.length >= 2 && pattern[1] === '*';
return isNextPatternWildCard
? isMatch(text, pattern.slice(2)) ||
(isFirstMatch && isMatch(text.slice(1), pattern))
: isFirstMatch && isMatch(text.slice(1), pattern.slice(1));
};
* DP - Top Down
* Matrix - Memoization
* Time O(N * M) | Space O(N * M)
* https://leetcode.com/problems/regular-expression-matching/
* @param {string} s
* @param {string} p
* @return {boolean}
*/
var isMatch = (
text,
pattern,
row = 0,
col = 0,
memo = initMemo(text, pattern),
) => {
const hasSeen = memo[row][col];
if (hasSeen) return memo[row][col];
const isEqual = col === pattern.length;
const ans = isEqual
? row === text.length
: check(
text,
pattern,
row,
col,
memo,
);
memo[row][col] = ans;
return ans;
};
var initMemo = (text, pattern) =>
new Array(text.length + 1)
.fill()
.map(() =>
new Array(pattern.length + 1).fill(false),
);
var check = (text, pattern, row, col, memo) => {
const isTextDefined = row < text.length,
isTextAndPatternEqual = pattern[col] === text[row],
isPatternPeriod = pattern[col] === '.',
isFirstMatch =
isTextDefined && (isTextAndPatternEqual || isPatternPeriod),
isNextPatternWildCard =
col + 1 < pattern.length && pattern[col + 1] === '*';
return isNextPatternWildCard
? isMatch(text, pattern, row, col + 2, memo) ||
(isFirstMatch && isMatch(text, pattern, row + 1, col, memo))
: isFirstMatch && isMatch(text, pattern, row + 1, col + 1, memo);
};
* Time O(N * M) | Space O(N * M)
* @param {string} s
* @param {string} p
* @return {boolean}
*/
var isMatch = (text, pattern) => {
const tabu = initTabu(text, pattern);
search(text, pattern, tabu);
return tabu[0][0];
};
var initTabu = (text, pattern) => {
const tabu = new Array(text.length + 1)
.fill()
.map(() =>
new Array(pattern.length + 1).fill(false),
);
tabu[text.length][pattern.length] = true;
return tabu;
};
var search = (text, pattern, tabu) => {
for (let row = text.length; 0 <= row; row--) {
for (let col = pattern.length - 1; 0 <= col; col--) {
const isTextDefined = row < text.length,
isTextAndPatternEqual = pattern[col] === text[row],
isPatternPeriod = pattern[col] === '.',
isFirstMatch =
isTextDefined && (isTextAndPatternEqual || isPatternPeriod),
isNextPatternWildCard =
col + 1 < pattern.length && pattern[col + 1] === '*';
tabu[row][col] = isNextPatternWildCard
? tabu[row][col + 2] || (isFirstMatch && tabu[row + 1][col])
: isFirstMatch && tabu[row + 1][col + 1];
}
}
};