JavaInterview JavaInterview
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)

『Java面试+Java学习』
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)
  • 指南
  • 简历

  • Java

  • 面试

  • 算法

  • algorithm
  • leetcode
JavaInterview.cn
2026-04-03
目录

2002. 两个回文子序列长度的最大乘积Java

文章发布较早,内容可能过时,阅读注意甄别。

# 题目

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

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

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

示例 1: two-palindromic-subsequences.png example-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 只含有小写英文字母。

# 思路

//转化为求解最长回文子序列问题

# 解法

class Solution {
//转化为求解最长回文子序列问题
public int maxProduct(String s) {
        char[] cs = s.toCharArray();
        int n = s.length(), max = (1<<n) - 1, ans = 0;
        for (int mask = 1; mask < max; ++mask) {
            ans = Math.max(ans, longestPalindromeSubSeq(cs, mask) * longestPalindromeSubSeq(cs, mask ^ max));
        }
        return ans;
    }

    int longestPalindromeSubSeq(char[] cs, int mask) {
        int n = cs.length;
        int[][] f = new int[n][n];
        for (int len = 1; len <= n; ++len) {
            for (int l = 0; l + len <= n; ++l) {
                int r = l + len - 1;
                if ((mask & (1 << l)) == 0 || (mask & (1 << r)) == 0) {
                    if (len == 2) {
                        f[l][r] = (mask & (1 << l)) != 0 || (mask & (1 << r)) != 0 ? 1 : 0;
                    } else if (len >2) {
                        f[l][r] = Math.max(f[l + 1][r], f[l][r - 1]);
                    }
                    continue;
                }
                if (len == 1) {
                    f[l][r] = 1;
                } else if (len == 2) {
                    f[l][r] = cs[l] == cs[r] ? 2 : 1;
                } else {
                    f[l][r] = Math.max(f[l + 1][r], f[l][r - 1]);
                    f[l][r] = Math.max(f[l][r], f[l + 1][r - 1] + (cs[l] == cs[r] ? 2 : 0));
                }
            }
        }
        return f[0][n - 1];
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
#Java
最近更新
01
1644.测试路径 Java
04-03
02
1887. 使数组元素相等的减少操作次数 Java
04-03
03
1889. 装包裹的最小浪费空间 Java
04-03
更多文章>
Theme by Vdoing | Copyright © 2019-2026 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式