00 | 01 | 02 |
10 | 11 | 12 |
20 | 21 | 22 |
a | b | a |
for (int L = 2; L <= len; L++) {
// 枚举左边界,左边界的上限设置可以宽松一些
for (int i = 0; i < len; i++) {
// 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
int j = L + i - 1;
// 如果右边界越界,就可以退出当前循环
if (j >= len) {
break;
}
if (charArray[i] != charArray[j]) {
dp[i][j] = false;
}
外层第一次循环 外层第二次循环..... 外层第Len次循环
j = 1;i = 0~len-1 ; j = 2; i=0 j = Len;i=0;
a | b | a | |
a | |||
b | |||
a |
最长回文子串
buffer:
true | len-2 | len-1 |
true | len-1 | |
true |
长度小于等于2的另作处理
循环从倒数第三行开始,列从倒数第一列开始,除去行与列相等的情况外
数组变化情况
1 | len-2 | len-1 | ||
2 | len-2 | len-1 | ||
3 | len-2 | len-1 |
倒过来循环可以使buffer[i][j] 获取 buffer[i+1][j-1]的状态从而使得动态规划执行。
public String longestPalindrome(String s) {
int len = s.length();
int maxlen = 1;
int[][] buffer = new int[len][len];
char[] charArray = s.toCharArray();
// int this = 0;
int begin = 0;
if(len<2){
return s;
}
//从后向前遍历字符串中所有子串
for(int i=len-2;i>=0;i--){
for(int j=len-1;j>i;j--){
if(charArray[i]==charArray[j]){
if(j-i+1 <=3){
buffer[i][j] = 1;
if(j-i+1>maxlen){
maxlen = j-i+1;//更新maxlen
begin = i ;
}
}else{
buffer[i][j] = buffer[i+1][j-1];//判定之前的子串是否相等
if(buffer[i][j]==1&&j-i+1>maxlen){//大于之前的maxlen就更新
maxlen = j-i+1;
begin = i;
}
}
}else{
buffer[i][j] = 0;
}
}
}
return s.substring(begin, begin + maxlen);
}