首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >LeetCode 2002. 两个回文子序列长度的最大乘积(状态压缩+枚举状态子集+预处理)

LeetCode 2002. 两个回文子序列长度的最大乘积(状态压缩+枚举状态子集+预处理)

作者头像
Michael阿明
发布2022-01-07 11:20:22
发布2022-01-07 11:20:22
5380
举报

文章目录

1. 题目

给你一个字符串 s ,请你找到 s 中两个 不相交回文子序列 ,使得它们长度的 乘积最大 。 两个子序列在原字符串中如果没有任何相同下标的字符,则它们是 不相交 的。

请你返回两个回文子序列长度可以达到的 最大乘积

子序列 指的是从原字符串中删除若干个字符(可以一个也不删除)后,剩余字符不改变顺序而得到的结果。如果一个字符串从前往后读和从后往前读一模一样,那么这个字符串是一个 回文字符串 。

示例 1:

代码语言:javascript
复制
输入: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. 解题

类似题目:LeetCode 1178. 猜字谜(状态压缩+枚举二进制子集+哈希)

  • 枚举状态子集。

2.1 超时

226 / 226 个通过测试用例

代码语言:javascript
复制
class Solution {
public:
    int maxProduct(string s) {
        int n = s.size();
        int ans = 1, state = (1<<n)-1;
        for(int i = state; i; i=state&(i-1))
        {
            int left = ~i&state;
            for(int k = left; k; k=left&(k-1))
                ans = max(ans, process(s, i)*process(s, k));
        }
        return ans;
    }
    int process(string& s, int num)
    {
        int n = s.size();
        string t;
        for(int i = 0; i < n; ++i)
        {
            if(num&(1<<i))
                t.push_back(s[i]);
        }
        int ans = 0, i = 0, j = int(t.size())-1;
        while(i < j)
        {
            if(t[i] == t[j])
            {
                i++, j--;
                ans += 2;
            }
            else
                break;
        }
        if(i < j) return 0;
        if(i == j) return ans+1;
        else return ans;
    }
};

2.2 预处理优化

对于判断是否是回文的操作预先进行处理

代码语言:javascript
复制
class Solution {
public:
    int maxProduct(string s) {
        int n = s.size();
        vector<int> palind = process(s);
        int ans = 1, state = (1<<n)-1;
        for(int i = state; i; i=state&(i-1))
        {
            int left = ~i&state;
            for(int k = left; k; k=left&(k-1))
                ans = max(ans, palind[i]*palind[k]);
        }
        return ans;
    }
    vector<int> process(string& s)
    {
        int n = s.size();
        vector<int> palind(1<<n, 0); 
        for(int state = (1<<n)-1; state; state--)
        {
            string t;
            for(int i = 0; i < n; ++i)
            {
                if(state&(1<<i))
                    t.push_back(s[i]);
            }
            int ans = 0, i = 0, j = int(t.size())-1;
            while(i < j)
            {
                if(t[i] == t[j])
                {
                    i++, j--;
                    ans += 2;
                }
                else
                    break;
            }
            if(i < j) ;
            if(i == j) palind[state] = ans+1;
            else palind[state] = ans;
        }
        return palind;
    }
};

128 ms 7.1 MB C++


我的CSDN博客地址 https://michael.blog.csdn.net/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/09/12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1. 题目
  • 2. 解题
    • 2.1 超时
    • 2.2 预处理优化
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档