题目
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
代码
暴力匹配
- 时间复杂度 O(N^3)
- 空间复杂度 O(1)
public String longestPalindrome(String str) {
int n = str.length();
if (n < 2) {
return str;
}
int maxLen = 1;
int begin = 0;
char[] charArray = str.toCharArray();
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (j - i + 1 > maxLen && validPalindromic(charArray, i, j)) {
maxLen = j - i + 1;
begin = i;
}
}
}
return str.substring(begin, begin + maxLen);
}
private boolean validPalindromic(char[] charArray, int left, int right) {
while (left < right) {
if (charArray[left] != charArray[right]) {
return false;
}
left++;
right--;
}
return true;
} 动态规划
- 时间复杂度 O(N^2)
- 空间复杂度 O(N^2)
public String longestPalindrome(String str) {
int n = str.length();
if (n < 2) {
return str;
}
int maxLen = 1;
int begin = 0;
char[] charArray = str.toCharArray();
boolean[][] dp = new boolean[n][n];
for (int i = 0; i < n; i++)
dp[i][i] = true;
for (int j = 1; j < n; j++) {
for (int i = 0; i < j; i++) {
if (charArray[i] != charArray[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] && j - i + 1 > maxLen) {
maxLen = j - i + 1;
begin = i;
}
}
}
return str.substring(begin, begin + maxLen);
} 中心扩散法
- 时间复杂度 O(N^2)
- 空间复杂度 O(1)
public String longestPalindrome(String str) {
int n = str.length();
if (n < 2) {
return str;
}
int maxLen = 1;
String res = str.substring(0, 1);
for (int i = 0; i < n - 1; i++) {
String oddStr = centerSpread(str, i, i);
String evenStr = centerSpread(str, i, i + 1);
String maxLenStr = oddStr.length() > evenStr.length() ? oddStr : evenStr;
if (maxLenStr.length() > maxLen) {
maxLen = maxLenStr.length();
res = maxLenStr;
}
}
return res;
}
private String centerSpread(String s, int left, int right) {
int len = s.length();
int i = left, j = right;
while (i >= 0 && j < len) {
if (s.charAt(i) == s.charAt(j)) {
i--;
j++;
} else {
break;
}
}
return s.substring(i + 1, j);
} 中心扩散法的改进
public String longestPalindrome(String str) {
if (str == null || str.length() < 1) return "";
if (str.length() == 1) return str;
int[] range = new int[2];
char[] arr = str.toCharArray();
for (int i = 0; i < arr.length; i++) {
i = findLongest(arr, i, range);
}
return str.substring(range[0], range[1] + 1);
}
private int findLongest(char[] str, int low, int[] range) {
int high = low;
while (high < str.length - 1 && str[high + 1] == str[low])
high++;
int ans = high;
while (low > 0 && high < str.length - 1 && str[low - 1] == str[high + 1]) {
low--;
high++;
}
if (high - low > range[1] - range[0]) {
range[0] = low;
range[1] = high;
}
return ans;
} 
京公网安备 11010502036488号