回文子串演算法

2021-08-26 08:45:52 字數 1879 閱讀 6400

兩層迴圈對字串中所有的子串進行定位,進而判斷是否是回文子串,複雜度o(n^3)。

方法簡單,易想到,但暴力,易超時。

for(i=0;imax)    //最長更新}}

還是使用兩層迴圈對子串定位,b[i][j]表示以i,j 為邊界的子串是否是回文。

不同的是使用動態規劃,通過子結構的遞推關係來求取最優解,

b[i][j] = (s[i]==s[j])&&ispa(b,i+1,j-1)        // i位置與j位置相同,則判斷其去掉兩邊後的子串

出口:  i==j  b[i][j]=1

但是時間複雜度o(n^2),還是易超時

//b[m][m]中每個元素初始化為0

for(i = 0; i < m; i++)

for(j = i + 1; j < m; j++)

if(ispa(b, i, j) == 1 && j - i > mj - mi)

mj = j; mi = i;

//ispa函式定義如下

ispa(int b , int i, int j)

if(b[i][j] != 0)

return b[i][j];

if(j <= i)

b[i][j] = 1;

else

b[i][j] = (b[i] == b[j]) && ispa(b, i + 1, j - 1);

return b[i][j];

下面介紹manacher,複雜度o(n)。

原串:abcdcbaf

下標 id01

2345

6789

1011

1213

1415

16拷貝串#a

#b#c

#d#c

#b#a

#f#陣列p12

1212

1812

1212

12容易證明,p[id] - 1 就是回文子串在原串中的長度,如上例中,最長子串為 abcdcba ,長度為7,p[8] - 1 = 7。

演算法關鍵在於如何求出p。

變數 maxid 記錄掃瞄串時所到達的最右邊的下標;

id 記錄掃瞄到最右邊串時當前子串的中心;

這個是leetcode裡面longest palindromic substring的回答: 

#define min(a,b) (a) > (b)? (b): (a)

char* longestpalindrome(char* s) , maxid = 0, id = 0, leng, j, start = 0;

//拷貝陣列

auxstr[0] = '^';

for (i = 0; s[i] != '\0'; ++i)

auxstr[i+1+i] = '#';

auxstr[i+1+i+1] = '\0';

for (i = 1; auxstr[i] != '\0'; i++)

if (p[start] < p[i])

start = i;

}i = (start - p[start])/2;

leng = p[start] - 1;

for (j = 0; j < leng; ++i)

auxstr[j] = '\0';

return auxstr;

}longest palindromic substring

(Manacher)演算法 O n 回文子串

資料 網路 參見 問題描述 輸入乙個字串,求出其中最大的回文子串。子串的含義是 在原串中連續出現的字串片段。回文的含義是 正著看和倒著看相同,如abba和yyxyy。解析 這裡介紹o n 回文子串 manacher 演算法 演算法基本要點 首先用乙個非常巧妙的方式,將所有可能的奇數 偶數長度的回文子...

回文子串 manarcher演算法

對於一般的回文子串的計算方法列舉每乙個字元s i 作為回文串的中心,然後分為奇數回文串和偶數回文串來進行遍歷兩端,演算法複雜度o n 2 int palindromestring const char s return ans 該演算法是o n 的複雜度,對於任意字串例如abc首先先變成 a b c...

O n 回文子串(Manacher)演算法

o n 回文子串 manacher 演算法 資料 網路 參見 問題描述 輸入乙個字串,求出其中最大的回文子串。子串的含義是 在原串中連續出現的字串片段。回文的含義是 正著看和倒著看相同,如abba和yyxyy。解析 這裡介紹o n 回文子串 manacher 演算法 演算法基本要點 首先用乙個非常巧...