给你一个字符串 s ,请你找到 s 中两个 不相交回文子序列 ,使得它们长度的 乘积最大 。两个子序列在原字符串中如果没有任何相同下标的字符,则它们是 不相交 的。
请你返回两个回文子序列长度可以达到的 最大乘积 。
子序列 指的是从原字符串中删除若干个字符(可以一个也不删除)后,剩余字符不改变顺序而得到的结果。如果一个字符串从前往后读和从后往前读一模一样,那么这个字符串是一个 回文字符串 。
示例 1:
输入:s = "leetcodecom"
输出:9
解释:最优方案是选择 "ete" 作为第一个子序列,"cdc" 作为第二个子序列。
它们的乘积为 3 * 3 = 9 。
示例 2:
输入:s = "bb"
输出:1
解释:最优方案为选择 "b" (第一个字符)作为第一个子序列,"b" (第二个字符)作为第二个子序列。
它们的乘积为 1 * 1 = 1 。
示例 3:
输入:s = "accbcaxxcxx"
输出:25
解释:最优方案为选择 "accca" 作为第一个子序列,"xxcxx" 作为第二个子序列。
它们的乘积为 5 * 5 = 25 。
提示:
2 <= s.length <= 12
s 只含有小写英文字母。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-product-of-the-length-of-two-palindromic-subsequences
解法一:状态压缩
本题的数据范围为[2, 12],所以本题可以利用状态压缩找出所有的回文子序列后,再对没有相交的回文子序列进行两两相乘,取最大的乘积。
class Solution {
bool check(const string &str, const int &len)
{
for (int i = 0; i < len - i; i++)
{
if (str[i] != str[len - 1 - i])
return false;
}
return true;
}
public:
int maxProduct(string s) {
int len = s.length();
int num = 1 << len;
vector<pair<int, int>> ps;
for (int i = 1; i < num; ++i)
{
string str = "";
int count = 0;
for (int j = 0; j < len; ++j)
{
if ((i&(1 << j)) == (1 << j))
{
str += s[j];
++count;
}
}
if (check(str, count))
ps.push_back(make_pair(i, count));
}
int pLen = ps.size();
int ans = 0;
for (int i = pLen-1; i >=0; --i)
{
for (int j = i + 1; j < pLen; ++j)
{
if ((ps[i].first&ps[j].first) == 0) //判断这两子序列是否相交
ans = max(ans, ps[i].second*ps[j].second);
}
}
return ans;
}
};
方法二:dfs
对于字符串中的每个字符,可以在最终答案的子序列1中,也可以在子序列2中,也可以都不在。根据这种思路进行dfs。
class Solution {
int ans;
bool check(const string &s)
{
int len = s.length();
for (int i = 0; i < len - 1 - i; ++i)
{
if (s[i] != s[len - 1 - i])
return false;
}
return true;
}
//对于s1与s2,也可以用引用提升速度
void dfs(const string &s, const int &n, string &s1, string &s2, int nowId)
{
if (nowId == n)
{
if (check(s1) && check(s2))
ans = max(ans, (int)(s1.length()*s2.length()));
return;
}
dfs(s, n, s1, s2, nowId + 1);
s1+=s[nowId];
dfs(s, n, s1, s2, nowId + 1);
s1.pop_back(); //移除最后一个的时间复杂度为O(1)
s2+=s[nowId];
dfs(s, n, s1, s2, nowId + 1);
s2.pop_back();
return;
}
public:
int maxProduct(string s) {
ans = 0;
string s1 = "", s2 = "";
int n = s.length();
dfs(s, n, s1, s2, 0);
return ans;
}
};