5.最长回文子串
1.动态规划
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
boolean[][] dp = new boolean[n][n];
int start = 0, maxLen = 1;
char[] str = s.toCharArray();
for(int len = 2;len <= n;len++){
for(int i = 0;i < n;i++){
int j = i + len - 1;
if(j >= n) break;
if(str[i] != str[j]) dp[i][j] = false;
else if(j - i < 3)
dp[i][j] = true;
else dp[i][j] = dp[i+1][j-1];
if(dp[i][j] && len > maxLen){
start = i;
maxLen = len;
}
}
}
return s.substring(start, start+maxLen);
}
}
2.中心扩散算法
class Solution {
public String longestPalindrome(String s) {
int start = 0, maxLen = 1;
int n = s.length();
for(int i = 0;i < n;i++){
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i+1);
int len = Math.max(len1, len2);
if(len > maxLen){
maxLen = len;
start = i - (maxLen-1)/2;
}
}
return s.substring(start, start+maxLen);
}
public int expandAroundCenter(String s, int left, int right){
while(left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)){
left--;right++;
}
return right - left - 1;
}
}
3. 马拉车算法
131.分割回文串
动规+回溯!
class Solution {
boolean[][] dp;
List<List<String>> ans = new ArrayList<>();
List<String> ls = new ArrayList<>();
int n;
public List<List<String>> partition(String s) {
n = s.length();
dp = new boolean[n][n];
for(int i = 0;i < n;i++){
Arrays.fill(dp[i], true);
}
for(int i = n-1;i >= 0;i--){
for(int j = i+1;j < n;j++){
dp[i][j] = (s.charAt(i) == s.charAt(j)) && dp[i+1][j-1];
}
}
backTrace(s, 0);
return ans;
}
public void backTrace(String s, int start){
if(start == n){
ans.add(new ArrayList<String>(ls));
return;
}
for(int end = start;end < n;end++){
if(dp[start][end]){
ls.add(s.substring(start, end+1));
backTrace(s, end+1);
ls.remove(ls.size()-1);
}
}
}
}
132.分割回文串Ⅱ
双动规
class Solution {
public int minCut(String s) {
int n = s.length();
boolean[][] dp = new boolean[n][n];
for(int i = 0;i < n;i++){
Arrays.fill(dp[i], true);
}
for(int i = n-1;i >= 0;i--){
for(int j = i+1;j < n;j++){
dp[i][j] = (s.charAt(i) == s.charAt(j)) && dp[i+1][j-1];
}
}
int[] f = new int[n];
Arrays.fill(f, Integer.MAX_VALUE);
f[0] = 0;
for(int i = 1;i < n;i++){
if(dp[0][i]){
f[i] = 0;
}
else{
for(int j = 0;j < i;j++){
if(dp[j+1][i])
f[i] = Math.min(f[i], f[j]+1);
}
}
}
return f[n-1];
}
}