Skip to content

Commit

Permalink
Merge branch 'neetcode-gh:main' into 14-longest-common-prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
UdayGarg authored Oct 4, 2022
2 parents 7ebd964 + c50d6fa commit b866064
Show file tree
Hide file tree
Showing 11 changed files with 1,307 additions and 342 deletions.
112 changes: 86 additions & 26 deletions javascript/10-Regular-Expression-Matching.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,98 @@
/**
* 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 = function (s, p) {
var lenS = s.length;
var lenP = p.length;
var map = {};
var isMatch = (text, pattern) => {
const isBaseCase = (pattern.length === 0);
if (isBaseCase) return (text.length === 0);

return check(0, 0);
const isTextAndPatternEqual = (pattern[0] === text[0]),
isPatternPeriod = (pattern[0] === '.'),
isFirstMatch = (text && (isTextAndPatternEqual || isPatternPeriod)),
isNextPatternWildCard = (pattern.length >= 2 && pattern[1] === '*');

function check(idxS, idxP) {
if (map[idxS + ':' + idxP] !== undefined) {
return map[idxS + ':' + idxP];
}
return isNextPatternWildCard/* Time O((N + M) * 2^(N + (M / 2))) | Space O(N^2 + M^2) */
? (isMatch(text, pattern.slice(2)) || (isFirstMatch && isMatch(text.slice(1), pattern)))
: (isFirstMatch && isMatch(text.slice(1), pattern.slice(1)));
};

if (idxS > lenS) {
return false;
}
/**
* 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];

if (idxS === lenS && idxP === lenP) {
return true;
}
const isEqual = (col === pattern.length);
const ans = isEqual
? row === text.length
: check(text, pattern, row, col, memo);/* Time O(N * M) | Space O(N * M) */

if (p[idxP] === '.' || p[idxP] === s[idxS]) {
map[idxS + ':' + idxP] =
p[idxP + 1] === '*'
? check(idxS + 1, idxP) || check(idxS, idxP + 2)
: check(idxS + 1, idxP + 1);
} else {
map[idxS + ':' + idxP] =
p[idxP + 1] === '*' ? check(idxS, idxP + 2) : false;
}
memo[row][col] = ans;
return ans;
}

var initMemo = (text, pattern) => new Array((text.length + 1)).fill()/* Time O(N) | Space O(N) */
.map(() => new Array((pattern.length + 1)).fill(false)) /* Time O(M) | Space O(M) */

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/* Time O(N * M) | Space O(N * M) */
? (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);/* Time O(N * M) | Space O(N * M) */

search(text, pattern, tabu); /* Time O(N * M) | Space O(N * M) */

return tabu[0][0];

return map[idxS + ':' + idxP];
}

var initTabu = (text, pattern) => {
const tabu = new Array((text.length + 1)).fill() /* Time O(N) | Space O(N) */
.map(() => new Array((pattern.length + 1)).fill(false));/* Time O(M) | Space O(M) */

tabu[text.length][pattern.length] = true; /* | Space O(N * M) */

return tabu
}

var search = (text, pattern, tabu) => {
for (let row = text.length; 0 <= row; row--){ /* Time O(N) */
for (let col = (pattern.length - 1); (0 <= col); col--){/* Time O(M) */
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 /* Space O(N * M) */
? tabu[row][col + 2] || (isFirstMatch && tabu[row + 1][col])
: isFirstMatch && tabu[row + 1][col + 1];
}
}
};
}
154 changes: 141 additions & 13 deletions javascript/1143-Longest-Common-Subsequence.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,144 @@
var longestCommonSubsequence = function (text1, text2) {
let m = text1.length,
n = text2.length,
DP = new Array(m + 1).fill(0).map((_) => new Array(n + 1).fill(0));

for (let x = m - 1; x >= 0; x--)
for (let y = n - 1; y >= 0; y--) {
if (text1[x] === text2[y]) {
DP[x][y] = 1 + DP[x + 1][y + 1];
} else {
DP[x][y] = Math.max(DP[x + 1][y], DP[x][y + 1]);
}
/**
* DP - Top Down
* Matrix - Memoization
* Time O(N * (M^2)) | Space O(N * M)
* https://leetcode.com/problems/longest-common-subsequence/
* @param {string} text1
* @param {string} text2
* @return {number}
*/
var longestCommonSubsequence = (text1, text2, p1 = 0, p2 = 0, memo = initMemo(text1, text2)) => {
const isBaseCase = ((p1 === text1.length) || (p2 === text2.length));
if (isBaseCase) return 0;

const hasSeen = (memo[p1][p2] !== null);
if (hasSeen) return memo[p1][p2];

return dfs(text1, text2, p1, p2, memo);/* Time O((N * M) * M)) | Space O((N * M) + HEIGHT) */
}

var initMemo = (text1, text2) => new Array((text1.length + 1)).fill()/* Time O(N) | Space O(N) */
.map(() => new Array((text2.length + 1)).fill(null)); /* Time O(M) | Space O(M) */

var dfs = (text1, text2, p1, p2, memo) => {
const left = longestCommonSubsequence(text1, text2, (p1 + 1), p2, memo); /* Time O(N * M) | Space O(HEIGHT) */

const index = text2.indexOf(text1[p1], p2); /* Time O(M) */
const isPrefix = (index !== -1);

const right = isPrefix
? (longestCommonSubsequence(text1, text2, (p1 + 1), (index + 1), memo) + 1)/* Time O(N * M) | Space O(HEIGHT) */
: 0;

memo[p1][p2] = Math.max(left, right); /* | Space O(N * M) */
return memo[p1][p2];
}

/**
* DP - Top Down
* Matrix - Memoization
* Time O(N * M) | Space O(N * M)
* https://leetcode.com/problems/longest-common-subsequence/
* @param {string} text1
* @param {string} text2
* @return {number}
*/
var longestCommonSubsequence = (text1, text2, p1 = 0, p2 = 0, memo = initMemo(text1, text2)) => {
const isBaseCase = ((p1 === text1.length) || (p2 === text2.length));
if (isBaseCase) return 0;

const hasSeen = (memo[p1][p2] !== null);
if (hasSeen) return memo[p1][p2];

return dfs(text1, text2, p1, p2, memo);/* Time O(N * M) | Space O((N * M) + HEIGHT) */
}

var initMemo = (text1, text2) => new Array((text1.length + 1)).fill()/* Time O(N) | Space O(N) */
.map(() => new Array((text2.length + 1)).fill(null)); /* Time O(M) | Space O(M) */

var dfs = (text1, text2, p1, p2, memo) => {
const left = (longestCommonSubsequence(text1, text2, (p1 + 1), (p2 + 1), memo) + 1);/* Time O(N * M) | Space O(HEIGHT) */
const right = /* Time O(N * M) | Space O(HEIGHT) */
Math.max(longestCommonSubsequence(text1, text2, p1, (p2 + 1), memo), longestCommonSubsequence(text1, text2, (p1 + 1), p2, memo));

const isEqual = (text1[p1] == text2[p2]);
const count = isEqual
? left
: right

memo[p1][p2] = count; /* | Space O(N * M) */
return memo[p1][p2];
}

/**
* DP - Bottom Up
* Matrix - Tabulation
* Time O(N * M) | Space O(N * M)
* https://leetcode.com/problems/longest-common-subsequence/
* @param {string} text1
* @param {string} text2
* @return {number}
*/
var longestCommonSubsequence = (text1, text2) => {
const tabu = initTabu(text1, text2);/* Time O(N * M) | Space O(N * M) */

search(text1, text2, tabu); /* Time O(N * M) | Space O(N * M) */

return tabu[0][0];
};

var initTabu = (text1, text2) =>
new Array((text1.length + 1)).fill() /* Time O(N) | Space O(N) */
.map(() => new Array((text2.length + 1)).fill(0));/* Time O(M) | Space O(M) */

var search = (text1, text2, tabu) => {
const [ n, m ] = [ text1.length, text2.length ];

for (let x = (n - 1); (0 <= x); x--) {/* Time O(N) */
for (let y = (m - 1); (0 <= y); y--) {/* Time O(M) */
tabu[x][y] = (text1[x] === text2[y]) /* Space O(N * M) */
? (tabu[x + 1][y + 1] + 1)
: Math.max(tabu[x + 1][y], tabu[x][y + 1]);
}
}
}

/**
* DP - Bottom Up
* Matrix - Tabulation
* Time O(N * M) | Space O(M)
* https://leetcode.com/problems/longest-common-subsequence/
* @param {string} text1
* @param {string} text2
* @return {number}
*/
var longestCommonSubsequence = (text1, text2) => {
const canSwap = (text2.length < text1.length);
if (canSwap) [ text1, text2 ] = [ text2, text1 ];

let tabu = initTabu(text1); /* Time O(M) | Space O(M) */

tabu = search(text1, text2, tabu);/* Time O(N * M) | Space O(M) */

return DP[0][0];
return tabu[0];
};

var initTabu = (text1) => new Array((text1.length + 1)).fill(0)

var search = (text1, text2, tabu) => {
for (let col = (text2.length - 1); (0 <= col); col--) {/* Time O(N) */
const temp = initTabu(text1); /* Space O(M) */

for (let row = (text1.length - 1); (0 <= row); row--) {/* Time O(M) */
const isEqual = (text1[row] == text2[col]);

temp[row] = isEqual /* Space O(M) */
? (tabu[(row + 1)] + 1)
: Math.max(tabu[row], temp[(row + 1)]);
}

tabu = temp; /* Space O(M) */
}

return tabu;
}
Loading

0 comments on commit b866064

Please sign in to comment.