NC17_最长回文子串
知识点:动态规划
题目链接
题目描述
对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串A以及它的长度n,请返回最长回文子串的长度。
输入: “abc1234321ab”,12
输出: 7
解题思路
- 令dp[i][j]表示A[i]至A[j]所表示的子串是否是回文子串
- 若A[i] = A[j],那么只要A[i+1]和A[j-1]是回文子串,A[i+1]至A[j-1]就是回文子串;
- 若A[i] != A[j],那A[i]至A[j]一定不是回文子串。
- 转移方程为 dp[i][j] = dp[i+1][j-1],A[i] == A[j]; 0,A[i]!=A[j]
- 边界:dp[i][i] = 1,dp[i][i+1] = (A[i]==A[i+1]?1:0)
- 如果按照i和j从小到大枚举 无法保证dp[i+1][j-1]被计算过
- 按照边界出发的原理,按子串的长度遍历,先枚举子串长度L,再枚举左端点,右端点i+L-1也可直接得到
代码
#include "cheader.h"
class Solution {
public:
int getLongestPalindrome(string A, int n) {
vector<vector<int>> dp(n,vector<int>(n,0));
if(n < 1)
return 0;
int ans = 1;
for(int i = 0; i < n; i++){
dp[i][i] = 1;
if(i+1 < n && A[i]==A[i+1]){
dp[i][i+1] = 1;
ans = 2;
}
}
for(int L = 3; L <= n; L++){
for(int i = 0; i+L-1 < n; i++){
int j = i+L-1;
if(A[i] == A[j] && dp[i+1][j-1] == 1){
dp[i][j] = 1;
ans = L;
}
}
}
return ans;
}
};
//leetcode 5. 最长回文子串
class Solution {
public:
pair<int, int> expand(const string& s, int left, int right) {
while (left >= 0 && right < s.size() && s[left] == s[right]) {
--left;
++right;
}
return {left + 1, right - 1};
}
string longestPalindrome(string s) {
int start = 0, end = 0;
for (int i = 0; i < s.size(); ++i) {
pair<int,int> x = expand(s, i, i);
pair<int,int> y = expand(s, i, i + 1);
if (x.second - x.first > end - start) {
start = x.first;
end = x.second;
}
if (y.second - y.first > end - start) {
start = y.first;
end = y.second;
}
}
return s.substr(start, end - start + 1);
}
};
int main()
{
string str("abc1234321ab");
Solution s;
cout<<s.getLongestPalindrome(str, 12)<<endl;
return 0;
}
今天也是爱zz的一天!