LeetCode: 5. 最長迴文子串

最長迴文子串

    迴文串(palindromic string)是指這個字符串無論從左讀還是從右讀,所讀的順序是一樣的;簡而言之,迴文串是左右對稱的。所謂最長迴文子串問題,是指對於一個給定的母串,找到的一個子串,是迴文串,並且長度最長

1、題目描述


Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example 2:

Input: "cbbd"
Output: "bb"

給定一個字符串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度爲1000。

示例 1:

輸入: "babad"
輸出: "bab"
注意: "aba"也是一個有效答案。

示例 2:

輸入: "cbbd"
輸出: "bb"

2、解題思路

2.1 窮舉法

​ 從字符串的左側,依次開始掃描,使用雙重循環,將所有的子串得到,然後判斷子串是否是迴文串,如果是,判斷長度是否是最長的,是最長的,就更新長度,並記錄這個字串

​ 不過需要分奇偶進行判斷

2.2 動態規劃

​ 動態規劃的思路就是,利用前面的結果進行判斷,例如

c[i,j]={c[i+1,j1]if s[i]=s[j]0if s[i]s[j]

​ 如上所示,i和j表示下標,i在前,j在後,因此,判斷的時候,如果判斷到當前的是否是迴文串,可以利用前面的結果來判斷是不是迴文串,比起前面構造的窮舉法,少了一層循環

2.3 分治法

​ 考慮迴文串中間部分是相同的,從母串的每一個字符入手,向左右判斷迴文串的長度

2.4 Manacher

​ 這個算法主要思想集中在將奇偶數的判斷放在一起

​ 例如下面的字符串

abcde
變成
#a#b#c#d#e#
長度從5變成了11,也就是 2*n+1

如果是ab
#a#b#
長度從2變成了5,同樣是2*n +1

也就是說,不管是奇數個還是偶數個字母,變換完成以後,都是奇數個

​ 然後進行分析,如果當前判斷的所在的下標被前面的迴文串的最右側下標所包含,,根據迴文串的對稱性,當前下標相對於前面的id有一個對稱點,這個點的迴文串長度我們已經算出來了,跟當前點到maxid的差值作比較,取小的,然後在這個基礎上繼續判斷迴文串的長度,也就是利用了前面應計算的結果,降低了計算量

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

char *longestPalindrome(char *s) {
    int i=0,id,maxid,ans=1,pos=0;
    //找到的最長迴文串的左端下標
    int left;
    //最長迴文串的臨時數組
    char * result;
    //字符串長度
    int str_length=0;
    while(s[i++]) str_length++;

    //初始化新的數組,存放每個元素對應的迴文半徑
    int p[2*str_length+3];
    //構造新的字符數組,用來計算
    char new_str[2*str_length+3];
    new_str[0]='$';
    new_str[1]='#';
    for (i =0;i< str_length;i++){
        new_str[2*i+2]=s[i];
        new_str[2*i+3]='#';
    }
    new_str[2*str_length+2]='\0';

    int len = 2*str_length+2;

    // 對每個字符求其迴文半徑,利用前面的數組
    // 最後面的'\0'不用求
    // 第一個字符"$",p[0]=1
    id = 0;
    maxid = 1;
    p[0] = 1;
    for (i=1;i<len;i++){
        // 判斷前一次的迴文最右端是不是包含當前判斷的字符
        if (maxid > i){
            p[i] = p[2*id-i] > (maxid-i)?(maxid-i):p[2*id-i];
        }else{
            p[i] = 1;
        }
        while(new_str[i+p[i]] == new_str[i-p[i]]){
            p[i]++;
        }
        if(p[i]+i> maxid){
            maxid = p[i]+i;
            id = i;
        }
        if (ans<p[i]){
            ans = p[i];
            pos = i;
        }
    }


    left = (pos-ans)/2;
    result = (char*)malloc(sizeof(char)*ans);
    for (i=0;i<ans-1;i++){
        result[i] = s[left+i];
    }
    result[ans-1] = '\0';

    return result;

}
int main() {
    char * aa= "abb";
    printf("%s\n", longestPalindrome(aa));
}

輸出:

/Users/zhangguohao/CLionProjects/untitled/cmake-build-debug/untitled
bb

Process finished with exit code 0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章