Add a recursive version of the Longest Common Substring.

This commit is contained in:
Oleksii Trekhleb 2023-01-30 09:01:49 +01:00
parent bcd1cc1b00
commit c9f1caf1ca
4 changed files with 57 additions and 0 deletions

View File

@ -7,6 +7,8 @@ describe('longestCommonSubstring', () => {
expect(longestCommonSubstring('', 'ABC')).toBe(''); expect(longestCommonSubstring('', 'ABC')).toBe('');
expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC'); expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC');
expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABC'); expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABC');
expect(longestCommonSubstring('sea', 'eat')).toBe('ea');
expect(longestCommonSubstring('algorithms', 'rithm')).toBe('rithm');
expect(longestCommonSubstring( expect(longestCommonSubstring(
'Algorithms and data structures implemented in JavaScript', 'Algorithms and data structures implemented in JavaScript',
'Here you may find Algorithms and data structures that are implemented in JavaScript', 'Here you may find Algorithms and data structures that are implemented in JavaScript',

View File

@ -0,0 +1,17 @@
import longestCommonSubstring from '../longestCommonSubstringRecursive';
describe('longestCommonSubstringRecursive', () => {
it('should find longest common substring between two strings', () => {
expect(longestCommonSubstring('', '')).toBe('');
expect(longestCommonSubstring('ABC', '')).toBe('');
expect(longestCommonSubstring('', 'ABC')).toBe('');
expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC');
expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABCA');
expect(longestCommonSubstring('sea', 'eat')).toBe('ea');
expect(longestCommonSubstring('algorithms', 'rithm')).toBe('rithm');
expect(longestCommonSubstring(
'Algorithms and data structures implemented in JavaScript',
'Here you may find Algorithms and data structures that are implemented in JavaScript',
)).toBe('Algorithms and data structures implemented in JavaScript');
});
});

View File

@ -1,4 +1,6 @@
/** /**
* Longest Common Substring (LCS) (Dynamic Programming Approach).
*
* @param {string} string1 * @param {string} string1
* @param {string} string2 * @param {string} string2
* @return {string} * @return {string}

View File

@ -0,0 +1,36 @@
/* eslint-disable no-param-reassign */
/**
* Longest Common Substring (LCS) (Recursive Approach).
*
* @param {string} string1
* @param {string} string2
* @return {number}
*/
export default function longestCommonSubstringRecursive(string1, string2) {
/**
*
* @param {string} s1
* @param {string} s2
* @return {string} - returns the LCS (Longest Common Substring)
*/
const lcs = (s1, s2, memo = {}) => {
if (!s1 || !s2) return '';
if (memo[`${s1}:${s2}`]) return memo[`${s1}:${s2}`];
if (s1[0] === s2[0]) {
return s1[0] + lcs(s1.substring(1), s2.substring(1), memo);
}
const nextLcs1 = lcs(s1.substring(1), s2, memo);
const nextLcs2 = lcs(s1, s2.substring(1), memo);
const nextLongest = nextLcs1.length >= nextLcs2.length ? nextLcs1 : nextLcs2;
memo[`${s1}:${s2}`] = nextLongest;
return nextLongest;
};
return lcs(string1, string2);
}