[LeetCode] Longest Palindrome Substring detailed analysis, leetcodepalindrome

Source: Internet
Author: User

[LeetCode] Longest Palindrome Substring detailed analysis, leetcodepalindrome

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

All the Examiners with DP questions are mentally ill .. (Tucao)

It seems that it is easy to get back to the question, so I will carefully analyze the DP practice today !! To solve my heartbroken feeling of being abused by the DP problem. If any error occurs, please point out ~


First, take this question and at least provide an O (n ^ 3) algorithm. The layer-2 for loop is added to check whether the substring is a text return. I have provided a code that must have timed out for your reference.

public String longestPalindrome(String s) {        if(s==null) return null;        // String[][] dp= new String[1000][1000];        // Arrays.fill(dp,1);        int max=1;        String result=s.substring(0,1);        for(int i=0;i<s.length()-1;i++){            for(int j=i+1;j<s.length();j++){                String temp=s.substring(i,j+1);                if(ifPalin(temp)){                    if(max<temp.length()){                        max=temp.length();                        result=temp;                    }                    if(max==s.length())                      return result;                }            }        }                return result;            }        public boolean ifPalin(String s){        if(s==null) return true;        int start=0;        int end=s.length()-1;                while(start<end){            if(s.charAt(start++)!=s.charAt(end--)){                return false;            }        }                return true;    }


This is obviously not enough! How to optimize it? You will think of this disgusting question, dp is inevitable. Therefore, all the situations must be taken into account to analyze the background.

The reason for the timeout of the Naive method in the above scheme is that the current sub-string has to be read every cycle. So how can we solve this repetitive task?

Based on the analysis of the background nature, we can see that if a sub string in the middle is a background, and if the sub strings have the same characters on both sides, the whole is also a background. For example:

Abcdcba: d is the background, and cdc is the background. If you think about it again, the cdc is the same as B on both sides, and the bcdcb is also the same. Okay, then abcdcba is a bounce message.

Through the previous example, we can see the answer directly. This is a special case. How is it better in general? Therefore, the first idea is derived from the forward thinking:

We declare a dp [] [] to store the status. For dp [I] [j], the meaning is that s. substring (I, j + 1) is not a background.

(1) Since we don't know where the center is, we can get the answer by expanding outward. The problem is solved by centering around each character and expanding outward and saving the largest volume!

We have to initialize dp. A single character is, so dp [I] [I] = true.

But there is another situation: abcddcba, there are two in the middle, not one, which can also constitute a reply. What should we do!

Let's take a look at s. charAt (I) = s. charAt (I + 1). If yes, it is a text return, we set dp [I] [I + 1] = true

With the basic case, we move the center point of a layer-1 for loop, and use two pointers, start and end, to expand the two cases respectively to analyze the input and find the maximum value. The Code is as follows:

Public String longestPalindrome (String s) {if (s = null) return null; boolean [] [] dp = new boolean [s. length ()] [s. length ()]; // define dp [I] [j] is if s. substring (I, j + 1) is palindrome: int max = 1; String result = s. substring (0, 1); for (int I = 0; I <s. length (); I ++) {dp [I] [I] = true;} for (int I = 0; I <s. length ()-1; I ++) {if (s. charAt (I) = s. charAt (I + 1) {dp [I] [I + 1] = true; result = s. substring (I, I + 2); max = 2 ;}} for (int I = 1; I <s. length ()-1; I ++) {int start = I-1, end = I + 1; // The case of aba while (start> = 0 & end <= s. length ()-1) {if (dp [I] [I] & s. charAt (start) = s. charAt (end) {dp [start] [end] = true; if (max <end-start + 1) {max = end-start + 1; result = s. substring (start, end + 1) ;}} else {break;} start --; end ++;} start = I-1; end = I + 2; // abba case while (start> = 0 & end <= s. length ()-1) {if (dp [I] [I + 1] & s. charAt (start) = s. charAt (end) {dp [start] [end] = true; if (max <end-start + 1) {max = end-start + 1; result = s. substring (start, end + 1) ;}} else {break;} start --; end ++ ;}} return result ;}

The code above is a bit too long and should be simplified. I am too lazy .. If you understand what it means, it's easy!

(2) The above solution is actually not quite dp. Let's consider the real dp Solution, but sometimes it is hard to come up with it .. Think about it ..

At least, if you see this, be patient and look at it again. You will certainly understand the process of dp solving this question:

The idea of dp is to use the previous results as the basis and then derive new results. (2) The idea is: What do you need to know if dp [I] [j] is a background based on the nature of the background?

The answer is:

1. s. charAt (I) = s. charAt (j)

2. dp [I + 1] [J-1] True

(This indicates whether the substring to which the current s. substring (I, j + 1) is saved is a text return .. For example: abccbmedium, if I = 0, j = 5, that is, abccbf, dp [I] [j], that is, whether abccbf is a reply, based on the previous results, if s. charAt (I) = s. charAt (j), and bccb is also a return, then dp [I] [j] is true. in this example,! = F, although dp [I + 1] [J-1] (bccb) is a back-to-text, it cannot be true)


So the essence of dp is like this: Through the previous results, we can deduce the present!

Another key point is the writing of dp. In the afternoon, I printed the dp array. the abscissa I starts from the back and goes forward, and j ends from the end to the end. 1 indicates true, which is a return text, and 0 indicates vice versa.

In dp, many of them come from the back. Of course we cannot remember the results, but we need to understand why.


Most of the text retrieval center should be in the center, so we can use the previous results from the back to the front. (The same is true in the past, but the parameters of the loop must be changed accordingly)

However, the above conditions are not enough! If dp [I + 1] [J-1] is false,

However, when the characters at the positions of I and j are the same and the distance is less than or equal to 2, they are all input files, because there are only three situations: a (I = j) aa (I = 0, j = 1) a * a (I = 0, j = 2) * represents any character. so we can use it as a response.

Then I will not move, and j will go on. If the distance exceeds 2, it may also encounter the same character as I. Is it a return? Then you have to see the dp [I + 1] [J-1] is not a back-to-text, if yes, record, determine whether it exceeds the current maximum length. If the value is exceeded, replace the longest string.

Looking at the second figure, the Three Ones are actually the derivation process of abccbadd In the example. When I = 2, j = 2 is the echo and record. I = 2, j = 3, and "cc" is a forward message. Continue. "Ccb" is not a reply,

The above is all the analysis. We recommend that you repeat the process by yourself. Only by understanding why this is done can we really understand dp and write a refined dp code.

: The following code is taken from the gods.

    public String longestPalindrome(String s) {          if(s==null || s.length()==1) return s;        boolean[][] dp= new boolean[s.length()][s.length()];        //define dp[i][j] is if s.substring(i,j+1) is palindrome:        int max=0;        String result=s.substring(0,1);        for(int i=s.length()-1;i>=0;i--){            for(int j=i;j<s.length();j++){                if(s.charAt(i)==s.charAt(j) && ((j-i<=2) || dp[i+1][j-1])){                    dp[i][j]=true;                    if(max<j-i+1){                        max=j-i+1;                        result=s.substring(i,j+1);                    }                }            }        }        return result;    }




How can I solve the problem of ACM input? Http: // acmswjtueducn/JudgeOnline/showproblem? Problem_id = 139

Read all input before further processing.

Read code:
Char * pBuf;
Memset (buf, 0, sizeof (buf); // buf is the array you previously defined
PBuf = buf;
While (gets (pBuf) pBuf + = strlen (pBuf );

In this way, all characters are read into the buf, and all linefeeds are removed. Next, you only need to implement the algorithm.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.