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 ...