LeetCode5, the longest text string

Title description

https://leetcode-cn.com/problems/longest-palindromic-substring/
Insert picture description here

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;

    }
}

Insert picture description here
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;

    }
}

Insert picture description here

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);
        

    }
}

Insert picture description here
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);
        

    }
}

Insert picture description here

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.
Insert picture description here

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);
        

    }
}

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_44861675/article/details/114497607