Title description
https://leetcode-cn.com/problems/longest-palindromic-substring/
Solution (existing problem-the order of dp array traversal is not clear yet)
Pass code for the first time:
class Solution {
public String longestPalindrome(String s) {
//字符串,使用双指针,则使用二维数组
if(s==null) return null;
if(s.length()==0) return null;
if(s.length()==1) return s;
int[][]dp = new int[s.length()][s.length()];
//边界初始化
for(int i=0;i<s.length();i++){
for(int j=0;j<s.length();j++){
if(i>j)
dp[i][j] = 0;
else if(i==j)
dp[i][j] = 1;
}
}
int max = 0;
//递推
for(int i=s.length()-1;i>=0;i--){
for(int j=s.length()-1;j>=0;j--){
if(i<j){
if(s.charAt(i)==s.charAt(j) && dp[i+1][j-1]== j-i-1){
dp[i][j] = j-i+1;//当前的字符串就是一个回文串
}else
dp[i][j] = Math.max(
dp[i+1][j],Math.max(1,//注意,可能是1最大了
dp[i][j-1])
);
}
if(max<dp[i][j]){
max = dp[i][j];
}
}
}
if(max==1) return s.substring(0,1);
// System.out.println(dp[0][s.length()-1]+" "+max);
//在dp数组里面找到和dp[0][s.length()-1]相等的值,那么它就是此时的最长回文字串
for(int i=0;i<s.length();i++){
for(int j=0;j<s.length();j++){
if(i<j && dp[i][j]==j-i+1 && dp[i][j]==max){
//必须是该字串
//System.out.println(dp[0][s.length()-1]+" "+max+" "+i+" "+j);
return s.substring(i,j+1);
}
}
}//找不到,则不存在
return null;
}
}
the second time:
class Solution {
public String longestPalindrome(String s) {
//字符串,使用双指针,则使用二维数组
if(s==null) return null;
if(s.length()==0) return null;
if(s.length()==1) return s;
int[][]dp = new int[s.length()][s.length()];
//边界初始化
int max = 0;
//递推
for(int i=s.length()-1;i>=0;i--){
for(int j=s.length()-1;j>=0;j--){
if(i>j)
dp[i][j] = 0;
else if(i==j){
dp[i][j] = 1;
}else{
if(s.charAt(i)==s.charAt(j) && dp[i+1][j-1]== j-i-1){
dp[i][j] = j-i+1;//当前的字符串就是一个回文串
}else
dp[i][j] = Math.max(
dp[i+1][j],Math.max(1,//注意,可能是1最大了
dp[i][j-1])
);
}
if(max<dp[i][j]){
max = dp[i][j];
}
}
}
//if(max==1) return s.substring(0,1);
// System.out.println(dp[0][s.length()-1]+" "+max);
//在dp数组里面找到和dp[0][s.length()-1]相等的值,那么它就是此时的最长回文字串
for(int i=0;i<s.length();i++){
for(int j=0;j<s.length();j++){
if(i<=j && dp[i][j]==j-i+1 && dp[i][j]==max){
//必须是该字串
//System.out.println(dp[0][s.length()-1]+" "+max+" "+i+" "+j);
return s.substring(i,j+1);
}
}
}//找不到,则不存在
return null;
}
}
the third time:
class Solution {
public String longestPalindrome(String s) {
//字符串,使用双指针,则使用二维数组
if(s==null) return null;
if(s.length()==0) return null;
if(s.length()==1) return s;
int[][]dp = new int[s.length()][s.length()];
//边界初始化
int max = 0;
int start=0,end=0;
//递推
for(int i=s.length()-1;i>=0;i--){
for(int j=s.length()-1;j>=0;j--){
if(i>j)
dp[i][j] = 0;
else if(i==j){
dp[i][j] = 1;
}else{
if(s.charAt(i)==s.charAt(j) && dp[i+1][j-1]== j-i-1){
dp[i][j] = j-i+1;//当前的字符串就是一个回文串
if(dp[i][j]>max){
start = i;
end = j;
}
}else
dp[i][j] = Math.max(
dp[i+1][j],Math.max(1,//注意,可能是1最大了
dp[i][j-1])
);
}
if(max<dp[i][j]){
max = dp[i][j];
}
}
}
return s.substring(start,end+1);
}
}
the fourth time:
class Solution {
public String longestPalindrome(String s) {
//字符串,使用双指针,则使用二维数组
if(s==null) return null;
if(s.length()==0) return "";
if(s.length()==1) return s;
int[][]dp = new int[s.length()][s.length()];
//边界初始化
int max = 1;//最大值起码等于1
int start=0,end=0;
//递推
for(int i=s.length()-1;i>=0;i--){
for(int j=s.length()-1;j>=0;j--){
if(i>j)
dp[i][j] = 0;
else if(i==j){
dp[i][j] = 1;
}else{
if(s.charAt(i)==s.charAt(j) && dp[i+1][j-1]== j-i-1){
//之前的dp[i+1][j-1]本身就是回文串
dp[i][j] = j-i+1;//当前的字符串就是一个回文串,一定会有一个dp[i][j]会进到这里
if(dp[i][j]>max){
//只要进到这里,整体是回文串
start = i;
end = j;
max = dp[i][j];
}
}else//这里因为i<j,所以i+1<=j,dp[i+1][j]>=1,所以我们去掉了比较1
dp[i][j] = dp[i+1][j]>dp[i][j-1]?dp[i+1][j]:dp[i][j-1];
}
}
}
return s.substring(start,end+1);
}
}
Found that there was a problem: the
code test passed, but
I don’t know why in the dp array. The final calculated result dp[0][s.length()-1] is sometimes not equal to max. I clearly defined dp[i][j] to mean s[i…j] The longest palindrome string.
Finally, I spent some time debugging in the idea, and found the problem:
that is, when dp[i][j-1] has not been calculated, I used it to recursively dp[i][j], so my j dimension The traversal direction of is wrong, resulting in dp[0][s.length()-1] not necessarily equal to max. But I am curious why it can pass the test.
Modified code:
class Solution {
public String longestPalindrome(String s) {
//字符串,使用双指针,则使用二维数组
if(s==null) return null;
if(s.length()==0) return "";
if(s.length()==1) return s;
int[][]dp = new int[s.length()][s.length()];//dp[i][j]定义为从s[i..j]的最长回文串
//边界初始化
int max = 1;//最大值起码等于1
int start=0,end=0;
//递推
for(int i=s.length()-1;i>=0;i--){
//从图上可视化看出应该使用后序遍历
for(int j=0;j<s.length();j++){
if(i>j)
dp[i][j] = 0;
else if(i==j){
dp[i][j] = 1;
}else{
if(s.charAt(i)==s.charAt(j) && dp[i+1][j-1]== j-i-1){
//之前的dp[i+1][j-1]本身就是回文串
dp[i][j] = j-i+1;//当前的字符串就是一个回文串,一定会有一个dp[i][j]会进到这里
if(dp[i][j]>max){
//只要进到这里,整体是回文串
start = i;
end = j;
max = dp[i][j];
}
}else//这里因为i<j,所以i+1<=j,dp[i+1][j]>=1,所以我们去掉了比较1
dp[i][j] = dp[i+1][j]>dp[i][j-1]?dp[i+1][j]:dp[i][j-1];
}
}
}
//按理来说dp[0][s.length()-1]表示的是最大值,应该=max
return s.substring(start,end+1);
}
}