字符串处理 —— 回文串相关 —— 求最长回文子串

【暴力枚举】

求最长回文串最容易的方法就是暴力枚举,求出字符串的每一个子串,然后判断是不是回文,找到最长的那个回文串

求每一个子串的时间复杂度为 O(N^2),判断一个子串是不是回文时间复杂度为 O(N),总的时间复杂度为 O(N^3)

string str;
void longestPalindrome(){
    int len=str.size();//字符串长度
    int maxlen=1;//最长回文串长度
    int start=0;//最长回文串起始地址
    for(int i=0;i=temp2&&j-i+1>maxlen){
                start=i;//更新回文串起始地址
                maxlen=j-i+1;//更新回文串长度
            }

        }
    }
    str=str.substr(start, maxlen);
}
int main(){
    cin>>str;
    longestPalindrome();
    cout<

【中心扩展法】

中心扩展就是将给定的字符串的每一个字母当做中心,然后向两边扩展,这样来寻找最长的回文串。其需要考虑两种情况:长度为奇数的回文串、长度为偶数的回文串。

时间复杂度为 O(N^2)

string str;
void longestPalindrome(){
    int len=str.size();//字符串长度
    int maxlen=1;//最长回文串长度
    int start=0;//最长回文串起始位置

    //长度为奇数的回文串
    for(int i=0;i=0 && rightmaxlen){
                start=left;//更新回文串起始位置
                maxlen=right-left+1;//更新回文串长度
            }
            left--;
            right++;
        }
    }

    //长度为偶数的回文串
    for(int i=0;i=0 && rightmaxlen){
                start=left;//更新回文串起始位置
                maxlen=right-left+1;//更新回文串长度
            }
            left--;
            right++;
        }
    }

    str=str.substr(start, maxlen);
}
int main(){
    cin>>str;
    longestPalindrome();
    cout <

【动态规划】

设 dp[j][i] 表示从 j 到 i 的子串是否是回文串,则:

dp[j][i]=\left\{\begin{matrix}true,\:\:j=i \\ str[i]=str[j],\:\:i-j=1 \\ str[i]=str[j],dp[j][i-1]=true,\:\:i-j>1 \end{matrix}\right.

当 dp[j][i]=true 时,表示从 j 到 i 的子串为回文子串,且子串起点位置为 j,长度为 i - j + 1

时间复杂度为:O(N ^ 2)

string str;
bool dp[N][N];
void longestPalindrome(){
    memset(dp,false,sizeof(dp));

    int len=str.size();//字符串长度
    int start=0;//最长回文子串起点
    int maxlen=1;//最长回文子串长度

    for(int i=0;i>str;
    longestPalindrome();
    cout<

【Manacher 算法】

时间复杂度:O(N)

算法详解:点击这里

 

你可能感兴趣的:(字符串处理——回文串相关)