题源力扣最长的回文子串
思路
因为回文串有一个特性,就是左右对称,所以判断一个区间是不是回文串只需要知道两个东西:
- 他的两个端点相不相等
- 去掉两个端点以后还是不是回文串
用数学公式表达就是
d p ( i , j ) = { d p [ i + 1 ] [ j − 1 ] , if (s[i]==s[j]) 0 , if s[i]!=s[j] dp_{(i,j)}=\begin{cases} dp[i+1][j-1],&\text{if (s[i]==s[j])}\\ 0,&\text{if s[i]!=s[j]} \end{cases} dp(i,j)={dp[i+1][j−1],0,if (s[i]==s[j])if s[i]!=s[j]
又因为本体的动态规划也是依据长度顺序去递推的,所以与这道题有些相似之处:dp基础。
代码
public:string longestPalindrome(string s) {int n = s.size();int dp[n][n];dp[0][0] = 1;for (int i = 1; i < n; i++) {dp[i][i] = 1;if (s[i] == s[i - 1]) {cout<<"the "<<i-1<<"th and the "<<i<<"th is equal"<<endl;dp[i - 1][i] = 1;}}
// for(int i=0;i<n;i++){
// for(int j=i+1;j<n;j++){
// cout<<i<<' '<<j<<"N "[dp[i][j]]<<endl;
// }
// }
// cout<<"first preprocess is down"<<endl;for (int k = 3; k <= n; k++) {for (int i = 0; i <= n - k; i++) {int j = i + k - 1;dp[i][j] = (dp[i + 1][j - 1] && s[i] == s[j]);}}
// for(int i=0;i<n;i++){
// for(int j=i+1;j<n;j++){
// cout<<i<<' '<<j<<"N "[dp[i][j]]<<endl;
// }
// }
// cout<<"preprocess is down"<<endl;
// int len=1,be=0;for (int k = n; k >= 1; k--) {for (int i = 0; i <= n - k; i++) {int j = i + k - 1;//cout<<i<<' '<<j<<"N "[dp[i][j]]<<endl;if (dp[i][j]) {be=i;len=k;return s.substr(be,len);}}}return s.substr(be,len);}
};