Question
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
Stats
Frequency | 2 |
Diffficulty | 4 |
Adjusted Difficulty | 4 |
Time to use | ---------- |
Ratings/Color = 1(white) 2(lime) 3(yellow) 4/5(red)
Analysis
There are 2 solutions. One is DP which is O(N^2) time and O(N^2) space. Another is “Search around corner”, which uses less space.
Solution
DP solution is straight-forward. Use 2D array to check palindrome intervals and make it as either true or false. Meanwhile, update longest.
O(N^2) time and O(N^2) space
Search around corner is basically iterate through the entire string and assume each char (or char pair) as center of the palindrome. The code isn’t difficult once you come up with the idea.
For more, read this post
O(N^2) time and O(1) space
My code
DP solution
public class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() == 0) {
return "";
}
String longest = "";
int len = s.length();
// dp[i][j] means substring of s from i to j is palindrome
boolean[][] dp = new boolean[len][len];
// why i decrease from (len-1) to 0, but j increase from i to (len-1)?
// think about it!
for (int i = len - 1; i >= 0; i--) {
for (int j = i; j < len; j++) {
if (i == j) {
dp[i][j] = true;
} else if (i + 1 == j) {
dp[i][j] = s.charAt(i) == s.charAt(j);
} else {
// important to note: dp[i+1][j-1]
// i depends on (i+1), so i from large to small
// j is just the opposite, small to large
dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i+1][j-1];
}
if (dp[i][j] && j + 1 - i > longest.length()) {
longest = s.substring(i, j + 1);
}
}
}
return longest;
}
}
Search around corner
public class Solution {
public String longestPalindrome(String s) {
if (s.length() <= 1)
return s;
String largest = s.substring(0, 1);
for (int i = 0; i < s.length(); i++) {
String first = this.searchAroundCenter(s, i, i);
String second = this.searchAroundCenter(s, i, i + 1);
if (first.length() < second.length())
first = second;
if (largest.length() < first.length())
largest = first;
}
return largest;
}
private String searchAroundCenter(String s, int a, int b) {
if (a < 0 || b > s.length() - 1)
return "";
while (s.charAt(a) == s.charAt(b)) {
a--;
b++;
if (a < 0 || b > s.length() - 1)
return s.substring(a + 1, b);
}
return s.substring(a + 1, b);
}
}