5. Longest Palindromic Substring

LeetCode

Approach 1: Dynamic Programming, Time complexity : O(n^2) (explanation)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Solution {
public static String longestPalindrome(String s) {
int n = s.length();
int palindromeStartsAt = 0, maxLen = 0;
boolean[][] dp = new boolean[n][n];
for(int j = 0; j < n; j++) {
for(int i = 0; i <= j; i++) {
dp[i][j] = (s.charAt(i) == s.charAt(j))&& ( j-i < 3 || dp[i+1][j-1]);
//update max palindrome string
if(dp[i][j] && (j-i+1 > maxLen)) {
palindromeStartsAt = i;
maxLen = j-i+1;
}
}
}
return s.substring(palindromeStartsAt, palindromeStartsAt+maxLen);
}
}
/*
class Solution {
public static String longestPalindrome(String s) {
int n = s.length();
int palindromeStartsAt = 0, maxLen = 0;
boolean[][] dp = new boolean[n][n];

for(int i = n-1; i >= 0; i--) {
for(int j = i; j < n; j++) {
dp[i][j] = (s.charAt(i) == s.charAt(j))&& ( j-i < 3 || dp[i+1][j-1]);
//update max palindrome string
if(dp[i][j] && (j-i+1 > maxLen)) {
palindromeStartsAt = i;
maxLen = j-i+1;
}
}
}
return s.substring(palindromeStartsAt, palindromeStartsAt+maxLen);
}
}*/

Approach 2: Expand Around Center, Time complexity : O(n^2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
private int expandAroundCenter(String s,int start,int end){
int l=start,r=end;
while(l>=0&&r<s.length()&&s.charAt(l)==s.charAt(r)){
l--;
r++;
}
return r-l-1;
}

public String longestPalindrome(String s) {
if(s==null||s.length()==0) return s;
int start=0,end=0;
for(int i=0;i<s.length();i++){
int len1=expandAroundCenter(s,i,i);
int len2=expandAroundCenter(s,i,i+1);
int len=Math.max(len1,len2);
if(len>end-start){
start=i-(len-1)/2;
end=i+len/2;
}
}
return s.substring(start,end+1);
}
}

Approach 3: Manacher’s Algorithm, Time complexity : O(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class Manacher {
private int[] p; // p[i] = length of longest palindromic substring of t, centered at i
private String s; // original string
private char[] t; // transformed string

public Manacher(String s) {
this.s = s;
preprocess();
p = new int[t.length];

int center = 0, right = 0;
for (int i = 1; i < t.length-1; i++) {
int mirror = 2*center - i;

if (right > i)
p[i] = Math.min(right - i, p[mirror]);

// attempt to expand palindrome centered at i
while (t[i + (1 + p[i])] == t[i - (1 + p[i])])
p[i]++;

// if palindrome centered at i expands past right,
// adjust center based on expanded palindrome.
if (i + p[i] > right) {
center = i;
right = i + p[i];
}
}

}
// Transform s into t.
// For example, if s = "abba", then t = "$#a#b#b#a#@"
// the # are interleaved to avoid even/odd-length palindromes uniformly
// $ and @ are prepended and appended to each end to avoid bounds checking
private void preprocess() {
t = new char[s.length()*2 + 3];
t[0] = '$';
t[s.length()*2 + 2] = '@';
for (int i = 0; i < s.length(); i++) {
t[2*i + 1] = '#';
t[2*i + 2] = s.charAt(i);
}
t[s.length()*2 + 1] = '#';
}

// longest palindromic substring
public String longestPalindromicSubstring() {
int length = 0; // length of longest palindromic substring
int center = 0; // center of longest palindromic substring
for (int i = 1; i < p.length-1; i++) {
if (p[i] > length) {
length = p[i];
center = i;
}
}
return s.substring((center - 1 - length) / 2, (center - 1 + length) / 2);
}
}

class Solution {
public String longestPalindrome(String s) {
Manacher m=new Manacher(s);
return m.longestPalindromicSubstring();
}
}

0%