最長回文子串的解法

2021-08-08 11:22:36 字數 1937 閱讀 8755

1、暴力法

最容易想到的就是暴力破解,求出每乙個子串,之後判斷是不是回文,找到最長的那個。

求每乙個子串時間複雜度o(n^2),判斷子串是不是回文o(n),兩者是相乘關係,所以時間複雜度為o(n^3)。

string findlongestpalindrome(string &s)  

if(tmp1>=tmp2&&j-i>maxlength)

} if(maxlength>0)

return s.substr(start,maxlength);//求子串

return null;

}

2、動態規劃

回文字串的子串也是回文,比如p[i,j](表示以i開始以j結束的子串)是回文字串,那麼p[i+1,j-1]也是回文字串。這樣最長回文子串就能分解成一系列子問題了。這樣需要額外的空間o(n^2),演算法複雜度也是o(n^2)。

首先定義狀態方程和轉移方程:

p[i,j]=0表示子串[i,j]不是回文串。p[i,j]=1表示子串[i,j]是回文串。

p[i,i]=1

p[i,j]{=p[i+1,j-1],if(s[i]==s[j])

=0 ,if(s[i]!=s[j])

string findlongestpalindrome(string &s)  

; for(int i=0;i}

for(int len=3;len

for(int i=0;i<=length-len;i++)//子串起始位址

} if(maxlength>=2)

return s.substr(start,maxlength);

return

null;

}

3、中心擴充套件

中心擴充套件就是把給定的字串的每乙個字母當做中心,向兩邊擴充套件,這樣來找最長的子回文串。演算法複雜度為o(n^2)。

但是要考慮兩種情況:

1、像aba,這樣長度為奇數。

2、想abba,這樣長度為偶數。

string findlongestpalindrome(string &s)  

j--;

k++;

} }

for(int i=0;ij--;

k++;

} }

if(maxlength>0)

return s.substr(start,maxlength);

return

null;

}

4、manacher法

manacher法只能解決例如aba這樣長度為奇數的回文串,對於abba這樣的不能解決,於是就在裡面新增特殊字元。我是新增了「#」,使abba變為a#b#b#a。這個演算法就是利用已有回文串的對稱性來計算的,具體演算法複雜度為o(n),我沒看出來,因為有兩個巢狀的for迴圈。

具體原理參考這裡。

測試**中我沒過濾掉「#」。

#define min(x, y) ((x)<(y)?(x):(y))  

#define max(x, y) ((x)<(y)?(y):(x))

string findlongestpalindrome3(string s)

length=length*2-1

;//新增#後字串長度

int *rad=new int[length]();

rad[0]=0;

for(int i=1,j=1,k;iint max=0;

int center;

for(int i=0;i}

return s.substr(center-max,2*max+1);

}

最長回文子串解法

沒咋麼過腦子,瞬間能想到的思路大概為 abcabcbb 比如這個字串 首先 宣告乙個陣列 裡面存放各種開分來的字串 切分條件是當這次迴圈的值 存在於當前的陣列中 像這樣abc bca cab abc bcb cb 最初的實現 var str 生成一些隨機字元 for var i 0 i 100000...

最長回文子串 解法一

其實最最簡單的演算法,也是效率最低的應該就是列舉子串,不過在這裡沒有必要拿來寫 解法一是在列舉子串上優化的 我們用 a,b 來表示子串,即從位置a到位置b的子串 假設現在我們已經知道了子串 x,y 不是回文串,那麼 x 1,y 1 x 2,y 2 x n,y n 還有可能是回文串嗎?當然不可能!所以...

最長回文串的解法

最長回文子串是最初我在網易筆試的時候遇見的,當時天真的把原字串s倒轉過來成為s 以為這樣就將問題轉化成為了求s和s 的 最長公共子串 的問題,而這個問題是典型的dp問題,我也在前面的文章中介紹了3中解決這個問題的方法。但是非常可惜,後來才知道這個演算法是不完善的。那麼到底為什麼呢?聽我慢慢道來。s ...