https://leetcode.cn/problems/longest-palindromic-substring
dp[i][j] 表示[i,j]之间的字符串是否是回文。
那么,如果chars[i] = chars[j]时,就有可能构成的子串为回文:
public class Solution {
public String longestPalindrome(String s) {
// 表示[i,j]之间的字符串是否是回文
boolean[][] dp = new boolean[s.length()][s.length()];
for(int i = 0; i < s.length(); i++) {
// 定义同一个位置的为true
dp[i][i] = true;
}
int maxLength = 0;
int left = 0, right = 0;
for (int i = s.length() - 1; i >= 0; i--) {
for (int j = i + 1; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
if (j - i < 3) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i+1][j-1];
}
if (dp[i][j] && (j - i + 1 > maxLength)) {
maxLength = j - i + 1;
left = i;
right = j;
}
}
}
}
return s.substring(left, right+1);
}
}
O(N^2)
O(N^2)
从左到右移动,每当移动一次后,往两边扩散,直到两侧边界字符不符合回文规则。
public class Solution {
int maxLength = 0;
int left = 0, right = 0;
public String longestPalindrome(String s) {
for (int i = 0; i < s.length() - 1; i++) {
// 字符串奇数长度时,中间一个字符串往两边扩散
spread(i, i, s);
// 字符串偶数长度时,中间两个字符串往两边扩散
spread(i, i+1, s);
}
return s.substring(left, right+1);
}
private void spread(int i, int j, String s) {
while (i >= 0 && j < s.length()) {
if (s.charAt(i) != s.charAt(j)) {
break;
}
i--;
j++;
}
// 把多减了、加了的补上
i++;
j--;
if (j - i + 1 > maxLength) {
left = i;
right = j;
maxLength = j - i + 1;
}
}
}
O(N^2)
O(1)