5. Longest Palindromic Substring [M] palindromic longest substring

topic

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example1:
  Input: "babad"
  Output: "bab"
  Note: "aba is also a valid answer. "
Example2:
  Input: "cbbd"
  Output: "bb"

Thinking


Ideas 1: Dynamic Programming

Step1: portray an optimal solution equation

\ (dp [i] [j ] \) represents the substring \ (s [i, \ cdots , j] \) whether a palindrome substring

Step2: the value of the recursive definition of the optimal solution

(1) Initialization:

  • dp[i][i] = true, i = [0, 1, ... ,n-1];
  • dp[i][i-1] = true, i = [1,2,...,n-1]
  • The rest is false

(2) the state transition table

  • dp[i][j] = (s[i] == s[j] && dp[i+1][j-1])

Update state transition table shown in Figure 1:

Step3: Calculated optimal solution

The state transition table, and a recurrence formula computing dp [i] [j].

Ideas 2: center expansion method

In the center of a character, a palindrome length were calculated. Palindromic substring is divided into odd, even, in both cases

  • Odd: traversing a character centered on the current determination
  • Even: the current traversal characters and their adjacent characters as the center judge

    Thinking 3: Manacher algorithm

    Also known as horse-drawn vehicles algorithm, we can solve the problem palindromic longest substring of a string are at a time complexity O (n) case.
    Manacher algorithm to increase the virtual string # (# is not really increased), so that the length is an odd number and an even number of sub-length of palindromic sequence considered together (so that the length of the substring are palindromic odd), as shown in FIG 1. To do: between the head, the tail, the adjacent character string virtual increase the # sign.

    Properties (1) Len array
Computing (2) Len array

Ideas 4: String slice (Python)

To detect whether palindromic using slicing string.

Tips


Dynamic Programming

C++


  • Ideas 1
class Solution {
public:
    string longestPalindrome(string s) {
        
        int nLength = s.size();
        if(nLength<1)
            return s;
        vector<vector<bool> > dp(nLength, vector<bool>(nLength, 0)); //dp[i][j]表示子串s[i,...,j]是否是一个回文子串
        int strBegin = 0;  //回文子串的开始
        int strEnd = 0; //回文子串的结尾
        
        //初始化
        for(int i = 1;i < nLength; i++){
            dp[i][i] = true;
            dp[i][i-1] = true;  //这个是针对子串长度为2,"bb"、"aa"的情况
        }
        dp[0][0] = true;
        
        //动态规划
        for(int i = 2;i <= nLength; i++){ //回文长度
            for(int j = 0; j <= nLength - i ; j++){  //回文子串起始
                
                if(s[j] == s[i+j - 1] && dp[j+1][i+j-2]){
                    dp[j][j+i-1] = true;
                    if(strEnd - strBegin + 1 < i){
                        strBegin = j;
                        strEnd = i + j -1; 
                    }
                }
            }
        }
        
        return s.substr(strBegin,strEnd-strBegin+1);
    }
};
  • Ideas 2
class Solution {
public:
    string longestPalindrome(string s) {
        
        int nLength = s.size();
        if(nLength == 1)
            return s;
        
        int strBegin = 0;
        int maxLength = 0;
        for(int i = 1;i < nLength; i++){
            
            //如果回文子串是奇数,以i为中心搜索
            int left = i - 1;
            int right = i + 1;
            while(left >=0 && right < nLength && s[left] == s[right] ) 
            {   
                left --;
                right ++;
            }
            
            if(right - left - 1 > maxLength){ //right -1 - (left + 1) + 1
                maxLength = right - left - 1;
                strBegin = left + 1;
            }
             
            //如果回文子串是偶数,
            left = i - 1;
            right = i;
            while(left >=0 && right < nLength && s[left] == s[right]){    
                left --;
                right ++;
            }
            
            if(right - left - 1 > maxLength){ 
                maxLength = right - left - 1;
                strBegin = left + 1;
            }
        } 
        return s.substr(strBegin,maxLength);
    }
};
  • 3 ideas
class Solution {
public:
    string longestPalindrome(string s) {
        
        if(s.size() <= 1)
            return s;
        
        string dummy = init(s);
        int nLength = dummy.size();
            
        int maxLen = 0;
        int mx = 0;
        int id = 0;
        vector<int> len(nLength, 0);
        
        for(int i =1;i< nLength - 1; i++){
            if(i < mx)
                len[i] = min(len[2*id -1], mx - i);
            else
                len[i] = 1;
            
            if(s[i - len[i]] == s[i + len[i]])
                len[i] ++;
            
            if(mx < i + len[i]){
                id = i;
                mx = i + len[i];
            }
        }
        
        int index = 0;
        for(int i = 1; i < nLength-1; i++){
            if(len[i] > maxLen){
                maxLen = len[i];
                index = i;
            }
        }
        return s.substr((index - maxLen)/2, maxLen-1);

    }
    
    
    //初始化
    string init(const string& s){
        string result = "$#";
        int nLength = s.size();
        
        for(int i=0;i < nLength; i++){
            
            result.push_back(s[i]);
            result.push_back('#');
        }
        
        return result;
    }   
};

Python

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        
        # 如果s为空
        if len(s) == 1:
            return s
        
        result = ""
        
        for i in range(len(s)):
            j = i + 1
            
            while j < len(s) and len(result) <= len(s[i:]):
                if s[i:j] == s[i:j][::-1] and len(s[i:j]) > len(result):
                    result = s[i:j]
                j += 1
                
        return result

reference

[1] https://blog.csdn.net/suool/article/details/38383045

Guess you like

Origin www.cnblogs.com/Jessey-Ge/p/10993415.html