Skip to content

Commit

Permalink
feat(dp): Longest Palindromic Substring
Browse files Browse the repository at this point in the history
  • Loading branch information
jeantimex committed Dec 16, 2017
1 parent 7d7fc2f commit cbaade4
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ A collection of JavaScript problems and solutions for studying algorithms.
### Dynamic Programming

- [Longest Increasing Subsequence](src/dynamic-programming/longest-increasing-subsequence.js)
- [Longest Palindromic Substring](src/dynamic-programming/longest-palindromic-substring.js)

## Author

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { assert } from 'chai';
import { longestPalindrome, longestPalindromeExpand } from '../longest-palindromic-substring';

describe('Longest Palindromic Substring', () => {
const testCases = [['babad', ['aba', 'bab']], ['aaaa', ['aaaa']]];

testCases.forEach((testCase, index) => {
it(`should get the longest palindromic substring using dynamic programming`, () => {
const s = testCase[0];
const expected = testCase[1];
const actual = longestPalindrome(s);
assert.include(expected, actual);
});

it(`should get the longest palindromic substring using expanding around center solution`, () => {
const s = testCase[0];
const expected = testCase[1];
const actual = longestPalindromeExpand(s);
assert.include(expected, actual);
});
});
});
85 changes: 85 additions & 0 deletions src/dynamic-programming/longest-palindromic-substring.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* Longest Palindromic Substring
*
* Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
*
* Example:
*
* Input: "babad"
*
* Output: "bab"
*
* Note: "aba" is also a valid answer.
* Example:
*
* Input: "cbbd"
*
* Output: "bb"
*
*/

/**
* Solution 1: Dynamic Programming
*
* @param {string} s
* @return {string}
*/
const longestPalindrome = s => {
const n = s.length;

const dp = [];
for (let i = 0; i < n; i++) {
dp[i] = [];
}

let result = '';
for (let i = n - 1; i >= 0; i--) {
for (let j = i; j < n; j++) {
dp[i][j] = s[i] === s[j] && (j - i <= 2 || dp[i + 1][j - 1]);

if (dp[i][j] && j - i + 1 > result.length) {
result = s.substring(i, j + 1);
}
}
}

return result;
};

/**
* Solution 2: Expand Around Center
*
* @param {string} s
* @return {string}
*/
const longestPalindromeExpand = s => {
let start = 0;
let end = 0;

for (let i = 0; i < s.length; i++) {
const len1 = expandAroundCenter(s, i, i);
const len2 = expandAroundCenter(s, i, i + 1);
const len = Math.max(len1, len2);

if (len > end - start) {
start = i - Math.floor((len - 1) / 2);
end = i + Math.floor(len / 2);
}
}

return s.substring(start, end + 1);
};

const expandAroundCenter = (s, left, right) => {
let L = left;
let R = right;

while (L >= 0 && R < s.length && s[L] == s[R]) {
L--;
R++;
}

return R - L - 1;
};

export { longestPalindrome, longestPalindromeExpand };

0 comments on commit cbaade4

Please sign in to comment.