动态规划—分割回文串-ii 解析+代码

2023-11-08

分割回文串-ii

题目链接:分割回文串-ii

在这里插入图片描述

思路:分割字符串s,使得子串都是回文串,最后获得最小分割次数。那么我们可以不断把字符串缩短,判断子串是否可以被分割成回文串,并且最小分割次数。这就是子问题分割了。所以我们可以使用动态规划。

状态:F(i):字符串s的前i个字符组成的子串的最小分割次数

状态转移方程:F(i):min(F(i),F(j)+1);j<i && s[j]~s[i] 是回文串
如果s[j]~s[i] 是回文串,因为要取最小分割次数,所以是F(i)当前分割次数和F(j)+1(前 j 个字符的分割次数+1)比较

而且每一次递推开始时,我们可以先判断当前子串自身是否是回文串,如果是,F(i) = 0,即不用分割

代码如下:

//判断字符串是否是回文串
	bool Ispalindrome(string&& str)
    {
        int left = 0;
        int right = str.size() - 1;
        while (left < right)
        {
            if (str[left] != str[right])
                return false;

            ++left;
            --right;
        }

        return true;
    }
	//主函数
    int minCut(string s)
    {
    	//准备一个存放分割次数的数组,并都初始化为int的最大值
    	//因为0号字符串是不需要分割,即本身回文,所以0号位置不需要
    	//所以需要准备size+1个位置
        vector<int>dp(s.size() + 1,INT_MAX);

        //因为substr函数是左闭右开,所以要遍历到size位置
        for (int i = 1; i <= s.size(); ++i)
        {
            //先判断当前子串是否是回文
            if(Ispalindrome(string(s.substr(0,i))))
            {
                dp[i]=0;
                continue;
            }
            //再分子串判断
            for (int j = 1; j < i; ++j)
            {
                if (Ispalindrome(string(s.substr(j, i-j))))
                        dp[i] = min(dp[j] + 1,dp[i]);//取最小
            }
        }
        return dp[s.size()];
    }

优化:当前代码的时间复杂度时n^3:i,j循环+检查回文串
我们可以直接将所有检查回文子串的结果放到二维数组中,以空间换时间,时间复杂度就到了n^2

子状态:从第一个字符到第二个字符是不是回文串,第1-3,2-5…
F(i,j):字符区间[i,j]是否是回文串
状态转移方程:F(i,j)有三种情况

  1. i==j时,代表只有一个字符,此时是回文的
  2. i+1==j时,代表有两个字符,此时需要判断s[i] == s[j]
  3. 其他情况,需要先判断s[i]==s[j],如果是相同的,那么再根据F[i+1][j-1],即往中间缩短的字符串是否是回文串

在这里插入图片描述

因为要依赖F[i+1][j-1]的结果,所以二维数组的更新是从右下角开始,并且是一个上对角矩阵
在这里插入图片描述

代码如下:

	//动态规划的判断回文串
    vector<vector<bool>> palindrome(string s)
    {
        int n=s.size();
        vector<vector<bool>> pal(n,vector<bool>(n,false));

        //从最后一行开始更新
        for(int i=n-1;i>=0;--i)
        {
            for(int j=i;j<n;++j)
            {
                if(i==j)
                    pal[i][j]=true;
                else if(i+1==j)
                    pal[i][j]=(s[i]==s[j]);
                else
                    pal[i][j]=(s[i]==s[j])&&(pal[i+1][j-1]);
            }
        }

        return pal;
    }

    int minCut(string s)
    {
        vector<int>dp(s.size() + 1);
        //dp数组要初始化
        //每个子串分割的最大次数就是下标-1
        //[0]号位置必须被初始化为-1
        //因为"aaaaa"这样的子串最小分割次数是-1+1=0
        for(int i=0;i<=s.size();++i)
            dp[i]=i-1;
        //获取回文子串的二维数组
        vector<vector<bool>> pal=palindrome(s);
        //要遍历到size位置
        for (int i = 2; i <= s.size(); ++i)
        {
            for (int j = 0; j < i; ++j)
            {
            	//第j~i-1的子串是否是回文串
                if (pal[j][i-1])
                        dp[i] = min(dp[j] + 1,dp[i]);//取最小
            }

        }
        return dp[s.size()];
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态规划—分割回文串-ii 解析+代码 的相关文章

随机推荐

  • 猜数字游戏(比大小)

    import random Sn random randint 0 100 函数返回n 生成一个在范围内的整数 例子 0 lt n lt 100 也可以用random random的函数 Gn int input 输入猜的数 N 1 whi
  • 2019安恒杯一月新春贺岁赛writeup

    WEB babyGo 提交你找到的字符串的md5值 考点 php反序列化 POP链构造
  • 字典树:Trie树(持续更新)

    字典树 Trie树 持续更新 今天开始学习字典树 顺便做做笔记 等多刷几道题再来更新一波经验 一 基本介绍 1 什么是字典树 字典树 又称单词查找树 前缀树 键树 是一种树形结构 是一种哈希树的变种 2 基本性质 1 根节点不包含字符 除根
  • 第十三届蓝桥杯单片机组—PCF8591使用

    蓝桥杯 PCF8591使用 00 了解PCF8591 01 PCF8591手册主要部分解读 控制字节 02 程序部分 ADC部分程序 DAC部分程序 03 总结 00 了解PCF8591 蓝桥杯的PCF8591是ADC DAC驱动芯片 大家
  • python 中定义的函数 如何在main中调用_python中main函数的用法

    什么场景下会有main函数 当该python脚本被作为模块 module 引入 import 时 其中的main 函数将不会被执行 main函数的作用 name main 是Python的main函数入口 并非说 加入这句才能使用pytho
  • js插件汇总

    1 NProgress显示顶部进度条 nprogress js 2 Decimal 浮点数运算的精度 decimal js 3 jquery画小图插件 jquery sparkline js 4 侧边栏导航 sidebar nav js B
  • apache模块开发 request_rec结构体中变量的值

    request rec结构体中用很多成员变量 这里只输出了char和int两种类型的值 source 1 include httpd h 2 include http config h 3 include http protocol h 4
  • STM32-(16):Systick 系统时钟

    上一篇 STM32 15 如何用ID号保护自己的劳动成果 下一篇 STM32 17 SPI与数码管 数码管 Systick的两大作用 1 可以产生精确延时 原先的Delay只是盲等 2 可以提供给操作系统一个单独的心跳 时钟 节拍 通常实现
  • 2021你有想尝试过副业吗?不如来学习3D游戏建模

    从2020 2021 我们会害怕 害怕经历这次疫情 自己会失业 但是同时也想保住一份工作 不知如果去做 那到底要不要先去找一条后路去做呢 起码还能给自己一条 活路 可是往往试着用哪一条活路 反而更多的是一事无成 我主业是一个3D模型模型师
  • 继承。。。

    继承 上节回顾 static 静态的 作用 可以用来修饰成员变量 gt 静态变量 类变量 静态变量它是随着类的加载而加载 它被这个类的所有对象共享 普通成员变量 实例变量 它是随着对象的创建而产生 在不同的对象之间 是相互独立的 可以用来修
  • java中的IO整理

    写在前面 本文章基本覆盖了java IO的全部内容 文章以例子为主 因为讲解内容的java书很多了 我觉的学以致用才是真 代码是写出来的 不是看出来的 最后欢迎大家提出意见和建议 案例1 创建一个新文件 1 2 3 4 5 6
  • linux安装nginx+php

    在centos服务器下 mkdir docker cd docker mkdir nginx mkdir php mkdir www 2 拉取镜像 docker pull nginx docker pull php 7 4 fpm dock
  • CentOS 7 分区方案

    通常系统盘都会选择性能较好SSD 一般在500G左右 这里就以500G硬盘为例 以下为CentOS 自动分区方案 分区应该按照实际服务器用途而定 自动分区方案将 home 空间分配太多了 多数情况下并不适用 必须存在的分区 分区是必须存在的
  • 如何卸载、删除Anaconda?

    Anaconda这么好用 为啥要删呢 当然是我之前装得乱七八糟 导致现在心情不好 我要把它全部删掉 ok 开始 删除思路 首先利用anaconda clean清理包清理配置文件 然后直接用安装目录下的卸载程序卸载即可 一 anaconda
  • 算法分析基础

    问题 如何比较不同算法的性能 分析算法的运行时间 算法分析的原则 归纳基本操作 如 运算 赋值 比较 统一机器性能 假设基本操作代价均为1 统一机器性能后 算法运行时间依赖于问题输入规模与实例 相同输入规模 实例影响运行 最好情况 不常出现
  • spark 参数调优3-Shuffle Behavior

    spark参数调优系列 目录地址 https blog csdn net zyzzxycj article details 81011540 Shuffle Behavior spark reducer maxSizeInFlight 默认
  • JSP中使用element-ui

    首先需要下载element ui 可以直接在github下载即可 script 引入 这样就可以使用了 如 this message 已经上传过了 无需重复上传 注 vue里面直接使用 this即可 jsp里面想使用的可以试试了
  • 浏览器客户端生成唯一标识码

    created this getFinger methods getFinger const canvas document createElement canvas const ctx canvas getContext 2d const
  • 人工智能:深度学习算法及应用——简单理解CNN卷积神经网络并python实现(带源码)

    深度学习算法及应用 一 实验目的 二 实验要求 三 实验的硬件 软件平台 四 实验原理 1 1 深度学习概述 1 2 深度学习的常见结构 1 3 卷积神经网络 CNN 卷积 池化 全连接网络 1 4 卷积神经网络的大致结构 1 5 参数学习
  • 动态规划—分割回文串-ii 解析+代码

    分割回文串 ii 题目链接 分割回文串 ii 思路 分割字符串s 使得子串都是回文串 最后获得最小分割次数 那么我们可以不断把字符串缩短 判断子串是否可以被分割成回文串 并且最小分割次数 这就是子问题分割了 所以我们可以使用动态规划 状态