动态规划将一个看似复杂的问题分解为一个个小问题,从而达到简化过程的目的
而最大回文子列的查找为其中典型
并让我们感受到很多问题只要寻找到其中本质,便能够直接地将之解出来
主要思路便是:
对于任意字符串,如果头尾字符相同,那么字符串的最长子序列等于去掉首尾的字符串的最长子序列加上首尾;如果首尾字符不同,则最长子序列等于去掉头的字符串的最长子序列和去掉尾的字符串的最长子序列的较大者。
题目地址:https://leetcode.com/problems/longest-palindromic-subsequence/#/description
题目:Longest Palindromic Subsequence
描述:
Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000.
Example 1:
Input:
"bbbab"
Output:
4
One possible longest palindromic subsequence is "bbbb".
Example 2:
Input:
"cbbd"
Output:
2
也就是在给定的一串字符中,找出其中能够回文的最长子列并输出长度
在自己的解法上,我直接地运用了string结构所带函数辅助解答
class Solution {
public:
int longest(string s){
int size = s.size();
if(size == 1)return 1;
if(s[0] == s[size - 1]){
if(size == 2)return 2;
s.pop_back();
s.erase(0, 1);
return 2 + longest(s);
}
if(s[0] != s[size - 1]){
if(size == 2)return 1;
string n = s;
s.pop_back();
n.erase(0, 1);
return max(longest(n), longest(s));
}
}
int longestPalindromeSubseq(string s) {
return longest(s);
}
};
然而由于erase和pop函数所耗费的时间太多,并不是最效率解
于是借鉴了leetcode中分享的解法:https://leetcode.com/problems/longest-palindromic-subsequence/#/solutions
class Solution {
public:
//lhs means left hand side, rhs means right hand side
int longestPalindromeSubseq(string s) {
if (s.empty()) return 0;
vector<vector<int>> longest(s.size(), vector<int>(s.size()));
for (int len=1; len<=s.size(); len++) {
for (int lhs=0; lhs+len<=s.size(); lhs++) {
int rhs = lhs+len-1;
if (lhs == rhs) {
longest[lhs][rhs] = 1;
} else if (lhs+1 == rhs) {
longest[lhs][rhs] = (s[lhs] == s[rhs]) ? 2 : 1;
} else {
int add = s[lhs] == s[rhs] ? 2 : 0;
longest[lhs][rhs] = max(max(longest[lhs][rhs-1], longest[lhs+1][rhs]), longest[lhs+1][rhs-1] + add);
}
}
}
return longest[0].back();
}
};
其中巧妙地运用了容器的二维数组,将s中i到j间最大子列长度收入v[s][j]中,方便查找。