給定乙個字串找出最長回文字串範圍,例如abaabac,最長回文為abaaba
1、使用暴力的演算法需要o(n^3)的複雜度,需要o(n^2)的複雜度去運算字串所用的子串,然後使用o(n)去判斷是否是回文串,從而定位最長的回文子串。
[cpp]
int lps_bl(char str, int len)
int i, j;
int start, end, max_lps;
for(i = 0; i < len; i++)
if(start >= end)
} }
} printf("lps_bl:%d\n", max_lps);
return max_lps;
}
可以看到這種演算法很容易理解,只是o(n^3)的複雜度相對比較高。
2、使用動態規劃的思想進行求解,思路是利用子串從短到長進行逐步的動態規劃求解,可以理解為從中心向兩邊擴散,如果乙個字串的子串是回文串,那麼就可以儲存這個狀態,然後從短向長蔓延進行計算:
當i == j 時 肯定是長度為1 的回文串,dp[i][j] = 1
當dp[i][j] == 1 時如果s[i-1] == s[j+1], dp[i][j] == 1,(如果子串是回文串,並且首尾相同,那麼當前的子串也是回文串)
當i+1 == j 時,s[i] == s[j], 那麼dp[i][j] == 1,這個狀態值在計算時會有些特殊,因為 j = i +1,那麼i-1和j+1會與i和j的值相反,但是不影響整體的計算。
[cpp]
#include
#include
#include
int lps_dp(char str, int len)
int dp[100][100] = ;
int i,j, m;
for(i = 0; i < 100; i++)
int start = 0;
int end = 0;
int max_lps = 0;
char buf[100] = ;
//printf("len:%d\n", len);
for(m = 1; m < len; m++)
}else if(dp[i+1][j-1] == 1 && str[i] == str[j])
} }
} //memcpy(buf, str+start, max_lps);
//buf[max_lps] = '\0';
//printf("max_len:%d\tlps:%s\n", max_lps, buf);
return max_lps;
}
3、受以上動態規劃演算法的啟發,可以考慮選取中間點,然後逐步向兩邊蔓延的策略進行回文串的判斷,這種方法相對於動態規劃的演算法更容易理解,而且空間複雜度會由o(n^2)變為o(1)
[cpp]
int lps_ext(char str, int len)
int i;
int max_lps = 1;
int start = 0;
char buf[100] = ;
for(i = 1; i < len; i++)
low--;
high++;
} low = i - 1;
high = i + 1;
while(low >= 0 && high < len && str[low] == str[high])
low--;
high++;
} }
memcpy(buf, str + start, max_lps);
printf("%d\tlps_ext:%s\n",max_lps, buf);
return max_lps;
} 下面介紹一種o(n)的演算法:manacher, 這個演算法開始理解起來比較複雜,但確實有一定的技巧性,第乙個技巧是將可能的回文串,無論是奇數個字元還是偶數個字元全部變為奇數,這樣有利於利用對稱性特徵進行計算,變換方式如下:
在每個字元的兩邊都插入乙個特殊的符號。比如 abba 變成 #a#b#b#a#, aba變成 #a#b#a#。 為了進一步減少編碼的複雜度,可以在字串的開始加入另乙個特殊字元,這樣就不用特殊處理越界問題,比如$#a#b#a#。
下面以字串12212321為例,經過上一步,變成了 s = "$#1#2#2#1#2#3#2#1#";
演算法引入兩個變數id和mx,id表示最長回文子串的中心位置,mx表示最長回文字串的邊界位置,即:mx=id+p[id]。
在這裡有乙個非常有用而且神奇的結論:如果mx > i,那麼p[i] >= min(p[2 * id - i], mx - i) 分開理解就是:
如果mx - i > p[j], 則p[i]=p[j]
否則,p[i] = mx - i.
最長回文串演算法
總的來說,最長回文串演算法分為以下幾種。通過遍歷整個字串來說實現對最長回文串的查詢 首先乙個字串所有子串,個數為n2個,然後逐個判斷遍歷即可,演算法複雜度o n3 如下 def is palindrome s str length len s for i in range str length 2 ...
最長回文串 演算法 4 求解最長回文子串
問題描述 給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。注釋 回文通俗的說就是正著念和反著念都一樣,如 上海自來水來自海上。示例 1 輸入 dabccbac 輸出 abccba 示例 2 輸入 cbbd 輸出 bb 解題思路 此處撰寫解題思路 遍歷每乙個索引,...
Manacher最長回文串演算法
在介紹演算法之前,首先介紹一下什麼是回文串,所謂回文串,簡單來說就是正著讀和反著讀都是一樣的字串,比如abba,noon等等,乙個字串的最長回文子串即為這個字串的子串中,是回文串的最長的那個。一.通常解決的問題 給定乙個字串,求出其最長回文子串。例如 1 s abcd 最長回文長度為 1 2 s a...