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-02-25
目录

1960. 两个回文子字符串长度的最大乘积Java

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

# 题目

给你一个下标从 0 开始的字符串 s ,你需要找到两个 不重叠的回文 子字符串,它们的长度都必须为 奇数 ,使得它们长度的乘积最大。

更正式地,你想要选择四个整数 i ,j ,k ,l ,使得 0 <= i <= j < k <= l < s.length ,且子字符串 s[i...j] 和 s[k...l] 都是回文串且长度为奇数。s[i...j] 表示下标从 i 到 j 且 包含 两端下标的子字符串。

请你返回两个不重叠回文子字符串长度的 最大 乘积。

回文字符串 指的是一个从前往后读和从后往前读一模一样的字符串。子字符串 指的是一个字符串中一段连续字符。

示例 1:

输入:s = "ababbb"
输出:9
解释:子字符串 "aba" 和 "bbb" 为奇数长度的回文串。乘积为 3 * 3 = 9 。

示例 2:

输入:s = "zaaaxbbby"
输出:9
解释:子字符串 "aaa" 和 "bbb" 为奇数长度的回文串。乘积为 3 * 3 = 9 。

提示:

  • 2 <= s.length <= 105
  • s 只包含小写英文字母。

# 思路

马拉车+前缀后缀和

# 解法

class Solution {
    public long maxProduct(String s) {
        String changed = process(s);
        int n = changed.length();
        int[] p = new int[n];
        int center = 0, mx = 0;
        for (int i = 1; i < n - 1; i++) {
            if (i < mx) {
                p[i] = Math.min(mx - i, p[center * 2 - i]);
            } else {
                p[i] = 0;
            }
            while (changed.charAt(i + p[i] + 1) == changed.charAt(i - p[i] - 1)) {
                p[i]++;
            }
            if (i + p[i] > mx) {
                mx = i + p[i];
                center = i;
            }
        }
        long[] leftDP = new long[n];
        long[] rightDP = new long[n];
        for (int i = 1; i < n; i++) {
            leftDP[i + p[i]] = Math.max(leftDP[i + p[i]], p[i] * 2 + 1);
            rightDP[i - p[i]] = Math.max(rightDP[i - p[i]], p[i] * 2 + 1);
        }
        for (int i = n - 2; i >= 1; i--) {
            leftDP[i] = Math.max(leftDP[i], leftDP[i + 1] - 2);
        }
        for (int i = 1; i <= n - 2; i++) {
            rightDP[i] = Math.max(rightDP[i], rightDP[i - 1] - 2);
        }
        for (int i = 1; i <= n - 2; i++) {
            leftDP[i] = Math.max(leftDP[i], leftDP[i - 1]);
        }
        for (int i = n - 2; i >= 1; i--) {
            rightDP[i] = Math.max(rightDP[i], rightDP[i + 1]);
        }
        long ans = 0;
        for (int i = 1; i < n - 2; i++) {
            ans = Math.max(ans, leftDP[i] * rightDP[i + 1]);
        }
        return ans;
    }
    public String process(String s) {
        StringBuilder ans = new StringBuilder("^");
        ans.append(s);
        ans.append("$");
        return ans.toString();
    }
}

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
40
41
42
43
44
45
46
47
48
49
50
51
52

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
#Java
最近更新
01
1644.测试路径 Java
02-25
02
1888. 使二进制字符串字符交替的最少反转次数 Java
02-25
03
1890. 2020年最后一次登录 Java
02-25
更多文章>
Theme by Vdoing | Copyright © 2019-2026 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式