LeetCode 2472.不重叠回文子字符串的最大数目:动态规划(贪心)

【LetMeFly】2472.不重叠回文子字符串的最大数目:动态规划(贪心)

力扣题目链接:https://leetcode.cn/problems/maximum-number-of-non-overlapping-palindrome-substrings/

给你一个字符串 s 和一个 整数 k

从字符串 s 中选出一组满足下述条件且 不重叠 的子字符串:

  • 每个子字符串的长度 至少k
  • 每个子字符串是一个 回文串

返回最优方案中能选择的子字符串的 最大 数目。

子字符串 是字符串中一个连续的字符序列。

示例 1 :

复制代码
输入:s = "abaccdbbd", k = 3
输出:2
解释:可以选择 s = "abaccdbbd" 中斜体加粗的子字符串。"aba" 和 "dbbd" 都是回文,且长度至少为 k = 3 。
可以证明,无法选出两个以上的有效子字符串。

示例 2 :

复制代码
输入:s = "adbcda", k = 2
输出:0
解释:字符串中不存在长度至少为 2 的回文子字符串。

提示:

  • 1 <= k <= s.length <= 2000
  • s 仅由小写英文字母组成

解题方法:动态规划

创建一个动态规划数组f,其中f[i]表示前i个字符中能选择的k回文子字符串的最大数目。

那么显然,对于f[i],我们有两种选择:

  1. 不选择以s[i-1]结尾的回文子字符串,那么f[i] = f[i-1]
  2. 选择以s[i-1]结尾的回文子字符串,那么我们需要找到一个长度至少为k的回文子字符串[j, i),那么f[i] = f[j] + 1

对于第二种情况,我们有必要从 k k k、 k + 1 k+1 k+1、 k + 2 k+2 k+2、...、 i i i都试试吗?没有。最多试一下 k k k和 k + 1 k+1 k+1保证奇数长度和偶数长度两种情况都考虑过就好了。

因为站在整体角度,如果存在 k + 2 k+2 k+2长的回文串的话, k k k长度也一定是回文串,没必要选 k + 2 k+2 k+2长。所以我们只需要考虑长度为 k k k和 k + 1 k+1 k+1的回文串。

  • 时间复杂度 O ( N 2 ) O(N^2) O(N2)
  • 空间复杂度 O ( N log ⁡ N ) O(N\log N) O(NlogN)

AC代码

C++
cpp 复制代码
/*
 * @LastEditTime: 2026-09-15 17:07:03
 */
class Solution {
private:
    bool ok(string& s, int l, int r) {  // [l, r)
        // len->i: 3->1 4->2 5->2 6->3
        for (int i = 0; i < (r - l) / 2; i++) {
            if (s[l + i] != s[r - i - 1]) {
                return false;
            }
        }
        return true;
    }
public:
    int maxPalindromes(string& s, int k) {
        int n = s.size();
        vector<int> f(n + 1);
        for (int i = k; i <= n; i++) {
            f[i] = f[i - 1];
            if (ok(s, i - k, i)) {
                f[i] = max(f[i], f[i - k] + 1);
            }
            if (i != k && ok(s, i - k - 1, i)) {
                f[i] = max(f[i], f[i - k - 1] + 1);
            }
        }
        return f.back();
    }
};

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源

相关推荐
Tisfy1 天前
LeetCode 0836.矩形重叠:xy两方向分别看
数学·leetcode·题解·模拟
青山木1 天前
Hot 100 --- 最长递增子序列
java·数据结构·算法·leetcode·动态规划
Logic1012 天前
C语言/数据动态规划题解:翻转一次子数组后的最大子数组和——四状态DP(O(n)时间O(1)空间)
c语言·数据结构·动态规划·时间复杂度·算法题·状态机dp·最大子数组和
Logic1012 天前
C语言/数据结构字符串题解:找出DNA序列中未配对的独特序列——排序+遍历(O(nlogn))
c语言·数据结构·字符串·数组·排序·时间复杂度·算法题
青山木2 天前
Hot 100 --- 打家劫舍
java·数据结构·算法·leetcode·动态规划
青山木2 天前
枚举类DP进阶:完全平方数与零钱兑换
java·数据结构·算法·leetcode·动态规划
wzdark3 天前
基于矩阵的动态规划路径问题性能优化4
线性代数·矩阵·动态规划
2601_962099464 天前
Python中的find()函数:用法和示例
python·字符串·索引·子字符串·find函数
伟大的车尔尼4 天前
贪心题目:三角形的最大周长
贪心