【动态规划】【回文】【字符串】1278分割回文串 III

简介: 【动态规划】【回文】【字符串】1278分割回文串 III

作者推荐

动态规划】【前缀和】【C++算法】LCP 57. 打地鼠

本文涉及知识点

动态规划汇总

LeetCode1278分割回文串 III

给你一个由小写字母组成的字符串 s,和一个整数 k。

请你按下面的要求分割字符串:

首先,你可以将 s 中的部分字符修改为其他的小写英文字母。

接着,你需要把 s 分割成 k 个非空且不相交的子串,并且每个子串都是回文串。

请返回以这种方式分割字符串所需修改的最少字符数。

示例 1:

输入:s = “abc”, k = 2

输出:1

解释:你可以把字符串分割成 “ab” 和 “c”,并修改 “ab” 中的 1 个字符,将它变成回文串。

示例 2:

输入:s = “aabbc”, k = 3

输出:0

解释:你可以把字符串分割成 “aa”、“bb” 和 “c”,它们都是回文串。

示例 3:

输入:s = “leetcode”, k = 8

输出:0

提示:

1 <= k <= s.length <= 100

s 中只含有小写英文字母。

动态规划

预处理

vNeedChange[i][j]表示将s[i,j]变成回文需要改变的字符数。 枚举中心和长度,时间复杂度:O(nn)。奇数长度回文和偶数长度回文,分别枚举。

动态规划的状态表示

pre[j] 表示s[0,j) 是由iK个回文串组成,最少改变的字符数。

动态规划的转移方程

dp[i]= M i n j = 0 i − 1 Min\Large_{j=0}^{i-1}Minj=0i1(pre[j]+vNeedChange[j][i-1]) 状态数:n,故空间复杂度:O(n)。转移每个状态的时间复杂度:O(n),故总时间复杂度:O(nn)。

动态规划的初始状态

全为0。

动态规划的填表顺序

i从1到s.length

动态规划的返回值

dp.back()

代码

核心代码

class Solution {
public:
  int palindromePartition(string s, int k) {
    m_c = s.length();
    vector<vector<int>> vNeedChange(m_c, vector<int>(m_c));
    for (int i = 0; i < m_c; i++)
    {
      int iNotSame = 0;
      for (int l = i, r = i; (l >= 0) && (r < m_c); l--,r++)
      {
        iNotSame += (s[l] != s[r]);
        vNeedChange[l][r] = iNotSame;
      }
    }
    for (int i = 0; i < m_c; i++)
    {
      int iNotSame = 0;
      for (int l = i, r = i+1; (l >= 0) && (r < m_c); l--, r++)
      {
        iNotSame += (s[l] != s[r]);
        vNeedChange[l][r] = iNotSame;
      }
    }
    vector<int> pre(m_c + 1, 1000);
    pre[0] = 0;
    while (k--)
    {
      vector<int> dp(m_c + 1, 1000);
      for (int i = 1; i <= m_c; i++)
      {
        for (int j = 0; j < i; j++)
        {
          dp[i] = min(dp[i], pre[j] + vNeedChange[j][i - 1]);
        }
      }
      pre.swap(dp);
    }
    return pre.back();
  }
  int m_c;
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{
  assert(t1 == t2);
}
template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
  if (v1.size() != v2.size())
  {
    assert(false);
    return;
  }
  for (int i = 0; i < v1.size(); i++)
  {
    Assert(v1[i], v2[i]);
  }
}
int main()
{ 
  string s ;
  int k = 0;
  {
    Solution sln;
    s = "abc", k = 2;
    auto res = sln.palindromePartition(s, k);
    Assert(1, res);
  }
  {
    Solution sln;
    s = "aabbc", k = 3;
    auto res = sln.palindromePartition(s, k);
    Assert(0, res);
  }
  
  {
    Solution sln;
    s = "leetcode", k = 8;
    auto res = sln.palindromePartition(s, k);
    Assert(0, res);
  }
}

2023年一月版

class Solution {

public:

int palindromePartition(string s, int k) {

vector<vector> vBeginEndNeedNum(s.length(), vector(s.length(),1000));

//vBeginEndNeedNum[i][j] s[i]到s[j]变成回文改变的次数

for (int i = 0; i < s.length(); i++)

{

{//处理奇数回文

int iNeedChange = 0;

vBeginEndNeedNum[i][i] = 0;

for (int len = 1;; len++)

{

const int iBegin = i - len;

const int iEnd = i + len;

if (iBegin < 0)

{

break;

}

if (iEnd >= s.length())

{

break;

}

if (s[iBegin] != s[iEnd])

{

iNeedChange++;

}

vBeginEndNeedNum[iBegin][iEnd] = iNeedChange;

}

}

{//处理偶数回文

int iNeedChange = 0;

for (int len = 1;; len++)

{

const int iBegin = i - len + 1;

const int iEnd = i + len;

if (iBegin < 0)

{

break;

}

if (iEnd >= s.length())

{

break;

}

if (s[iBegin] != s[iEnd])

{

iNeedChange++;

}

vBeginEndNeedNum[iBegin][iEnd] = iNeedChange;

}

}

}

vector pre = vBeginEndNeedNum[0];

for (int iSetp = 0; iSetp + 1 < k; iSetp++)

{

vector dp(s.length(),1000);

dp[0] = pre[0];

for (int i = iSetp+1; i < s.length(); i++)

{

for (int j = iSetp ; j < i; j++)

{

dp[i] = min(dp[i], pre[j] + vBeginEndNeedNum[j + 1][i]);

}

}

pre.swap(dp);

}

return pre[s.length() - 1];

}

};


相关文章
|
自然语言处理 BI 数据处理
【数据对比】综合分析百度情感分析以及华为情感分析的差异,我有了如下结果
【数据对比】综合分析百度情感分析以及华为情感分析的差异,我有了如下结果
541 0
|
2月前
|
弹性计算 运维 负载均衡
阿里云轻量应用服务器产品介绍、收费标准以及搭建个人博客教程参考
本文为大家介绍阿里云轻量应用服务器的产品优势、应用场景、使用须知、地域与网络连通性、与云服务器ECS的区别以及使用轻量应用服务器搭建WordPress个人博客的图文教程,以供大家了解和使用轻量应用服务器。
|
9月前
|
机器人 应用服务中间件 API
轻松集成私有化部署Dify文本生成型应用
Dify 是一款开源的大语言模型应用开发平台,融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者能快速搭建生产级生成式 AI 应用。通过阿里云计算巢,用户可以一键部署 Dify 社区版,享受独享的计算和网络资源,并无代码完成钉钉、企业微信等平台的应用集成。本文将详细介绍如何部署 Dify 并将其集成到钉钉群聊机器人和企业微信中,帮助您轻松实现 AI 应用的定义与数据运营,提升工作效率。
4870 65
轻松集成私有化部署Dify文本生成型应用
|
监控 安全 物联网
在使用物联网卡过程中的一些限制
在使用物联网卡(IoT卡)的过程中,确实存在一些限制和注意事项,这些限制主要来源于技术、安全、法规以及服务提供商的政策等多个方面。以下是一些常见的限制及操作建议:
|
机器学习/深度学习 数据可视化 算法
激活函数与神经网络------带你迅速了解sigmoid,tanh,ReLU等激活函数!!!
激活函数与神经网络------带你迅速了解sigmoid,tanh,ReLU等激活函数!!!
|
机器学习/深度学习 算法
【MATLAB】小波神经网络回归预测算法
【MATLAB】小波神经网络回归预测算法
227 1
|
算法 C语言
【软件工程题库】第五章 详细设计
【软件工程题库】第五章 详细设计
735 0
|
API 开发者 Docker
python中版本不兼容问题
【5月更文挑战第3天】python中版本不兼容问题
1728 2
|
存储 缓存 NoSQL
Redis从入门到精通之底层数据结构SDS(简单动态字符串)详解
SDS是Redis中的一种字符串类型,它是一种二进制安全的字符串,由简单动态字符串(SDS)实现。SDS支持多种数据结构,其中字符串(String)是最常用的一种数据结构之一。SDS的优点在于它可以避免C字符串常见的问题,比如缓冲区溢出和内存泄露等。SDS的常数复杂度获取字符串长度和杜绝缓冲区溢出可以避免使用strlen和strcat函数时的一些问题。同时,SDS的空间预分配和惰性空间释放两种策略可以减少修改字符串的内存重新分配次数。SDS也是二进制安全的,因为它不是以空字符串来判断字符串是否结束,而是以len属性表示的长度来判断字符串是否结束。SDS还兼容部分C字符串函数
3384 104
|
Java 测试技术 数据库
家政服务预约APP的系统设计与实现
家政服务预约APP的系统设计与实现
545 0