LeetCode 5. Longest Palindromic Substring / 516. Longest Palindromic Subsequence
5. Longest Palindromic Substring
暴力的话需要枚举开始下标i,结束下标j,并判断该字串是否为回文,需要O(n^3)时间。很明显,通过暴力并判断字串是否为回文效率很低,其并没有考虑到回文的性质。
方法一:DP
bool dp[i][j] 表示下标 i~j 的字串是否为回文
考虑到回文的特性,递推公式很容易得到: dp[i][j] = ( dp[i+1][j-1]==ture && s[i]==s[j] )
Base cases 也很容易想,dp[i][i] = true, dp[i][i+1] = ( s[i]==s[i+1] ) for all i
有一点需要注意的是,通过递推更新 dp[i][j] 的时候,i 需要从后向前遍历。可以结合dp矩阵的图想一下,这是由于每个点更新都需要依赖左下角的点,如果i从前向后遍历左下角的点有可能还没更新。
或者更新的时候用一个variable len,枚举i,然后j=i+len,从小到大构建。
class Solution { public: string longestPalindrome(string s) { int n=s.size(); bool dp[n][n]={false}; for (int i=0;i<n;++i) dp[i][i]=true; for (int i=0;i+1<n;++i) dp[i][i+1]=(s[i]==s[i+1]); for (int i=n-1-2;i>=0;--i) for (int j=i+2;j<n;++j) dp[i][j] = (dp[i+1][j-1] && s[i]==s[j]); string res=""; for (int i=0;i<n;++i){ for (int j=i;j<n;++j){ if (dp[i][j] && j-i+1>res.size()) res=s.substr(i,j-i+1); } } return res; } };
方法二:
考虑到回文的特性,枚举每一个回文的中心点,向两边扩展。对于长度为n的字符串,需要枚举2n-1个中心点。时间复杂度是O(n^2),但是空间复杂度为O(1),优于DP。
class Solution { public: string longestPalindrome(string s) { int n=s.size(); string res=""; int left, right; for (int i=0;i<n;++i){ left=right=i; while (left-1>=0 && right+1<n && s[left-1]==s[right+1]){--left; ++right;} if (right-left+1 > res.size()) res=s.substr(left,right-left+1); } for (int i=0;i<n-1;++i){ left=i; right=i+1; if (s[left]!=s[right]) continue; while (left-1>=0 && right+1<n && s[left-1]==s[right+1]){--left; ++right;} if (right-left+1 > res.size()) res = s.substr(left,right-left+1); } return res; } };
516. Longest Palindromic Subsequence
dp[i][i+1] 可以并到for循环里一起处理。
class Solution { public: int longestPalindromeSubseq(string s) { int n=s.size(); if (n==0) return 0; // dp[i][i] = 1; // dp[i][j] = max dp[i+1][j-1]+2 if s[i]==s[j] // dp[i+1][j] // dp[i][j-1] vector<vector<int>> dp(n,vector<int>(n,0)); for (int i=0;i<n;++i) dp[i][i]=1; for (int len=1;len<n;++len){ for (int i=0;i+len<n;++i){ int j=i+len; if (s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2; else dp[i][j]=max(dp[i+1][j],dp[i][j-1]); } } return dp[0][n-1]; } };

浙公网安备 33010602011771号