最長迴文子串

題目很簡單
一個字符串如果從左往右和從右往左讀的結果是一樣的,則稱爲迴文字符串。寫程序找出給定字符串的最長迴文子串。例如字符串 abcbabcb,有多個迴文字串 bcb,bab,cbabc,bcbabcb 等,其中最長迴文子串爲 bcbabcb。

有多種解法

1.中心擴展
思路就是枚舉迴文串中心對稱點,注意要區分奇偶情況即可。

int solve()
{
    int len = strlen(a);
    for(int i=1;i<len-1;i++){
        int m1,m2;
        m1=1;
        m2=0;
        int j=1;
        while(i-j>=0&&i+j<len&&a[i-j]==a[i+j]){
            m1+=2;
            j++;
        }

        if(i+1<len&&a[i]==a[i+1]){
            m2=2;
            j = 1;
            while(i-j>=0&&i+j+1<len&&a[i-j]==a[i+j+1]){
                m2+=2;
                j++;
            }
        }
        d[i] = max(m1,m2);
    }
    int ans = 1;
    for(int i=1;i<len-1;i++){
        ans = max(ans,d[i]);
    }
    return ans;
}

2.DP法
dp[i][j]表示的是字符串中下標i到j的子串a[i,j]是否爲迴文串,1表示是。
易知,當a[i]==a[j]時,若a[i,j]爲迴文串,a[i+1,j-1]也是迴文串;否則,a[i+1,j-1]也不是迴文串
初始時dp[i][i]=1;當a[i]==a[i+1]時,dp[i][i+1]=1。
要注意的是第一重循環枚舉的不是起始點,而是長度
因爲dp[i][j]是由dp[i+1][j-1]推出的,只有通過先枚舉長度,才能夠得到所有會用到的dp[i+1][j-1]。

int solve()
{
    int len = strlen(a);
    int ans = 1;
    for(int i=0;i<len;i++){
        dp[i][i]=1;
        if(i!=len-1&&a[i]==a[i+1]){
            dp[i][i+1]=1;
            ans = 2;
        }
    }
    for(int l=3;l<=len;l++){
        for(int i=0;i+l-1<len;i++){
            int j = i+l-1;
            if(a[i]==a[j]){
                dp[i][j] = dp[i+1][j-1];
                if(dp[i][j]) ans = l;
            }
            else{
                dp[i][j] = 0;
            }
        }
    }
    return ans;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章