灯笼裤配什么鞋子好看| 心电图hr是什么意思| 腿不自觉的抖是什么原因| 房水由什么产生| 维生素c什么时候吃效果最好| 苯丙氨酸是什么| 都有什么水果| 平均血小板体积偏高是什么意思| 脱发用什么药最好| 为什么肛门会出血| 旅游要带什么| 前列腺回声欠均匀什么意思| 起水痘需要注意什么| 鱼露是什么东西| 920是什么意思| 波涛澎湃是什么意思| ards是什么病| 下面痛是什么原因| 横截面是什么意思| 胆固醇和血脂有什么区别| 人为什么会得白血病| 意念是什么意思| 性病是什么病| 六月初五是什么日子| 奶豆腐是什么| 金的部首是什么| 下午一点多是什么时辰| 阳卦代表什么意思| 验血能查出什么| 晕菜是什么意思| 布谷鸟长什么样| 什么是雷达| 痤疮用什么药膏最有效| iqr是什么意思| 什么的腊梅| 吃什么治疗湿气重| 勃起不坚硬吃什么药| 食指长痣代表什么| 用什么泡水喝对肝脏好| 脂肪瘤吃什么药可以消除| 黄芪什么人不能喝| 拔罐的原理是什么| 吸尘器什么牌子好| 石斛不能和什么一起吃| 心脏早搏是什么原因造成的| 上午10点半是什么时辰| 倭瓜是什么瓜| 2037年是什么年| QQ什么意思| 望洋兴叹是什么意思| 剑桥英语和新概念英语有什么区别| 厌氧菌感染用什么药| 梦见买棺材是什么征兆| 微不足道是什么意思| 用眼过度用什么眼药水| pr在医学上是什么意思| 喉咙干是什么原因| 周正是什么意思| 莲是什么结构的字| 狗狗拉稀是什么原因| 18k金是什么| 手脚麻木吃什么药| 品牌主理人是什么意思| 灵魂摆渡人是什么意思| 痰湿瘀阻是什么症状| 狗为什么喜欢吃人屎| 梦见黑山羊是什么预兆| 孕期吃什么水果好| 钾高吃什么可以降下来| 频繁打喷嚏是什么原因| 炸鸡翅裹什么粉| 字字珠玑什么意思| 桃李是什么意思| cco是什么职位| 刘玄德属什么生肖| 阁是什么意思| 晚上睡觉多梦是什么原因| 12月2号什么星座| 逸五行属性是什么| 红枣不能和什么一起吃| 大脚骨疼是什么原因| 为什么医院不开金刚藤| 高血压吃什么药最好| 焦虑症吃什么中成药| saucony是什么品牌| 腹泻输液用什么药| 沙茶酱是什么做的| 1985年海中金命缺什么| 好好好是什么语气| 梵高属于什么画派| 小孩睡觉出汗是什么原因| 血包是什么意思| 为什么乳头会痛| 山药为什么煮熟了也麻口| 股癣用什么药膏好得快| 甄嬛传什么时候上映的| 金童玉女指什么生肖| 发烧呕吐吃什么药| 心脏早搏吃什么药| 吃什么能安神助睡眠| 清明为什么插柳枝| abs是什么材质| 救世主是什么意思| 头痒是什么原因| 什么是阴历| 凌迟是什么意思| 睡久了头疼是什么原因| 胃疼可以吃什么食物| 痛风是什么意思| 肾结石有什么症状表现| 眼睛红肿是什么原因引起的| 药店属于什么单位性质| 什么是甲减病| 什么是辛亥革命| 朱棣是朱元璋的什么人| 月子里吃什么饭最好| 细菌感染是什么引起的| 支气管哮喘吃什么药| 什么冲冲| 眼皮发黑是什么原因| 蚊子咬了用什么药膏| 牙齿出血是什么原因| 合胞病毒吃什么药| 外阴又疼又痒用什么药| 县副局长是什么级别| 属狗的和什么属相最配| 背疽是什么病| pic什么意思| 什么地叹气| 潘多拉魔盒是什么意思| 窦道是什么意思| 小孩经常口腔溃疡是什么原因| 小时的单位是什么| 情人总分分合合是什么歌| 超市理货员是做什么的| 肝功能七项是检查什么| 紫癜有什么危害| 血脂高吃什么能降下来| 一直打嗝是什么问题| 神疲乏力吃什么中成药| 吃什么可以散结节| leslie什么意思| 六月二十一是什么日子| 北京市长是什么级别| 春运是什么意思| 耳鸣吃什么药效果最好| 男性b超检查什么项目| 单亲是什么意思| 无什么无| 口腔医学是什么| 心花怒放是什么生肖| 什么姿势最深| 林冲为什么叫豹子头| 什么什么龙什么| 骨蒸潮热 是什么意思| 石几念什么| 气阴两虚吃什么药| 无异于是什么意思| 6月1日是什么星座| 多发结节是什么意思| 牛顿三大定律是什么| 贼眉鼠眼是什么生肖| 生病吃什么| 绿洲是什么意思| 脚背抽筋是什么原因引起的| 网线长什么样| 蹂躏是什么意思| 疤痕贴什么时候用最佳| 什么红| 市政府办公室主任是什么级别| 正财代表什么| g18k是什么金| 什么的冬瓜| 心脏看什么科| 阳痿吃什么药效果好| 轴位是什么意思| 女人腰疼是什么妇科病| 菇凉是什么意思| 钙不能和什么一起吃| 煤气罐在什么情况下会爆炸| 吃什么减肥最好最快| 蛇盘疮吃什么药| 菜园中有什么生肖| 封闭是什么意思| 林格液又叫什么| pm代表什么| 炒面用什么面条最好| 肝的主要功能是什么| 心脏不好有什么症状| 肠梗阻是什么意思| 确认妊娠是什么意思啊| resp是什么| 宫腔镜检查主要查什么| 淋巴发炎吃什么药好| 梦见小牛犊是什么预兆| 什么是大小周| 女人腿肿是什么原因引起的| bpo是什么意思啊| 4月29号是什么星座的| 扒灰什么意思| 3月4号什么星座| 吃什么对心脏好| 便秘吃什么药效果最好| 颈椎问题挂什么科| 如如不动什么意思| 右侧中耳乳突炎是什么意思| 眼睛看东西模糊是什么原因| 碳水化合物是什么东西| 梦见粉条是什么意思| 裙裤配什么鞋子好看| 补肾壮阳吃什么药好| 9k金是什么意思| 月亮星座是什么意思| 正襟危坐什么意思| 金银花不能和什么一起吃| 尿毒症是什么原因导致的| 大年初一是什么生肖| 脚板疼是什么原因| 孙权为什么不北伐| 白玫瑰的花语是什么| 阴道发炎用什么药| 疏肝理气是什么意思| 12年是什么年| 好人是什么意思| 电荷是什么| 苹果a1660是什么型号| 早上起来不晨勃是什么原因| hco3-是什么意思| 牛头不对马嘴是什么意思| 色散是什么意思| 包饺子用什么面粉| 梦见老公出轨了是什么征兆| 千岛酱是什么味道| 口腔溃疡挂什么科室| 消肿吃什么药| 不凝血是什么原因| 吃什么东西减肥| yg是什么意思| 低头头晕是什么原因| pdn是什么意思| 见性成佛是什么意思| 拍拖什么意思| 对数是什么意思| 52年属什么| 翡翠对人体有什么好处| 甲状腺手术后可以吃什么水果| 122是什么号码| 全职什么意思| 有什么好用的vpn| 左侧附件区囊性回声是什么意思| 时间单位是什么| 8月29日什么星座| 苹果和什么一起榨汁好喝| 公共关系是什么意思| 苏打水配什么好喝| 1987年属什么生肖| 大腿外侧是什么经络| 鼎字五行属什么| 宝宝咳嗽流鼻涕吃什么药| 穹隆什么意思| 肺栓塞的主要症状是什么| 什么是微商| 胡萝卜含有什么维生素| 共济会是什么组织| 百度

3 cheers for the Police.........SAFETY FIRST

百度   《我爱我家》由英达执导,梁左编剧,宋丹丹、文兴宇、杨立新、梁天等主演,讲述了90年代北京一个六口之家及他们的邻里、亲朋之间有趣的生活故事,于1993年首播40集,1994年续播80集。

35.回文子串

回文子串
给你一个字符串?s?,请你统计并返回这个字符串中?回文子串?的数目。

回文字符串?是正着读和倒过来读一样的字符串。

子字符串?是字符串中的由连续字符组成的一个序列。

示例 1:

输入: s = “abc”
输出: 3
解释: 三个回文子串: “a”, “b”, “c”

示例 2:

输入: s = “aaa”
输出: 6
解释: 6个回文子串: “a”, “a”, “a”, “aa”, “aa”, “aaa”

提示:

  • 1 <= s.length <= 1000
  • s?由小写英文字母组成

动态规划能将所有的子串是否是回文的信息,保存在dp表里面

dp[i] [j]表示s字符串[i,j]的子串,是否为回文串
image.png
如果在s[i]=s[j]的情况下,dp[i+1] [j-1]的状态是true的话,那么就说明dp[i] [j]是true的

我们这里是不需要进行初始化操作的

这个题要求我们返回回文的个数,那么我们直接返回dp表中true的个数就行了

class Solution

{

public:

? ? int countSubstrings(string s)

? ? {

? ? ? ? int n=s.size();

? ? ? ? vector<vector<bool>>dp(n,vector<bool>(n));//nxn规模的矩阵

? ? ? ? //dp[i][j] 是一个布尔值,用于表示子串 s[i...j] 是否是回文子串。

  

? ? ? ? int ret=0;

? ? ? ? for(int i=n-1;i>=0;i--)

? ? ? ? {

? ? ? ? ? ? for(int j=i;j<n;j++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(s[i]==s[j])

? ? ? ? ? ? ? ? ? ? dp[i][j]=i+1<j?dp[i+1][j-1]:true;//如果i+1<j的话,那就说明子串的长度大于2,所以我们就得考虑(i+1,j-1)这个区间的dp值是否为true了,如果是true的话,那么dp[i][j]这段区域就是true的,但是如果我们的i+1等于y的话,就说明我们这段区域的长度是等于2的,并且两个字符还是相等的,所以我们就返回true就行了

? ? ? ? ? ? ? ? ? ? //接着判断子串 s[i+1...j-1] 是否是回文。如果是回文,s[i...j] 也是回文;否则,如果 i+1 == j,即子串长度为 2,那么 s[i...j] 也是回文。

? ? ? ? ? ? ? ? if(dp[i][j]==true)ret++;//每次 dp[i][j] == true 时,表示 s[i...j] 是回文子串,ret 就增加 1。

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //循环结束之后整个dp表就保存着所有的子串的信息

? ? ? ? return ret;

? ? }

};

i是往左边进行移动的,从最后一个位置开始的
j是往右边进行移动的
image.png
image.png
image.png
我们是从后面往前面进行遍历操作的,而不是从开头往后面的

这样,每次计算 dp[i][j] 时,已经可以保证 dp[i+1][j-1] 的结果已经计算出来了,从而可以正确判断子串 s[i...j] 是否是回文。image.png

36.最长回文子串

最长回文子串
给你一个字符串?s,找到?s?中最长的?回文?子串。

示例 1:

输入: s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。

示例 2:

输入: s = “cbbd”
输出:“bb”

提示:

  • 1 <= s.length <= 1000
  • s?仅由数字和英文字母组成

这个题我们之前是使用中心扩展算法+双指针进行解决的,代码如下:

class Solution {

public:

? ? string longestPalindrome(string s)

? ? {

? ? ? ? //中心扩展算法

? ? ? ? int begin=0,len=0;//begin记录我们最终结果的起始位置,len记录我们最终的长度

? ? ? ? for(int i=0;i<s.size();i++)//依次枚举所有的中点

? ? ? ? {

? ? ? ? ? ? //先做一次奇数长度的扩展

? ? ? ? ? ? int left=i,right=i;

? ? ? ? ? ? while(left>=0&&right<s.size()&&s[left]==s[right])

? ? ? ? ? ? {

? ? ? ? ? ? ? ? //满足上面的条件我们就让两个指针进行移动,

? ? ? ? ? ? ? ? left--;

? ? ? ? ? ? ? ? right++;

? ? ? ? ? ? }

? ? ? ? ? ? if(right-left-1>len) //更新下我们回文段串最长的长度

? ? ? ? ? ? {

? ? ? ? ? ? ? ? begin=left+1;//更新下我们回文段的有效位置的开始位置

? ? ? ? ? ? ? ? len=right-left-1;

? ? ? ? ? ? }

  

? ? ? ? ? ? //偶数长度的扩展

? ? ? ? ? ? left=i,right=i+1;

? ? ? ? ? ? while(left>=0&&right<s.size()&&s[left]==s[right])

? ? ? ? ? ? {

? ? ? ? ? ? ? ? //满足上面的条件我们就让两个指针进行移动,

? ? ? ? ? ? ? ? left--;

? ? ? ? ? ? ? ? right++;

? ? ? ? ? ? }

? ? ? ? ? ? if(right-left-1>len)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? begin=left+1;//更新下我们回文段的有效位置的开始位置

? ? ? ? ? ? ? ? len=right-left-1;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //当这个for循环结束之后,那么begin就是存的是回文串的起始位置

? ? ? ? return s.substr(begin,len);

? ? }

};

但是这里呢,我们使用动态规划进行问题的解决

判断子串是否是回文->用dp表,统计所有的子串是否是回文的信息->根据dp表起始位置得到我们想要的结果

dp[i] [j]表示:s[i] [j]的子串是否为回文串

image.png
dp里面值为true的情况下,长度最大的子串的起始位置以及长度
基本原理就是在每次判断完do[i] [j]为回文串之后,我们就进行长度的更新操作了
最后循环结束我们就得到了最后的长度,进行返回就行了

class Solution {

public:

? ? string longestPalindrome(string s)

? ? {

? ? ? ? int n=s.size();

? ? ? ? vector<vector<bool>>dp(n,vector<bool>(n));//大小是n*n的

? ? ? ? //我们这里是不需要进行初始化操作的,我们能保证我们的数组不越界

  

? ? ? ? //我们的循环是从后面开始进行操作的

? ? ? ? int len=1,begin=0;//最小的长度肯定为1,起始的位置为0

? ? ? ? for(int i=n-1;i>=0;i--)

? ? ? ? {

? ? ? ? ? ? for(int j=i;j<n;j++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(s[i]==s[j])//前后两个字符是相同的

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? dp[i][j]=i+1<j?dp[i+1][j-1]:true;

? ? ? ? ? ? ? ? ? ? //如果此时的i+1<j的话,那么就说明此时的子串的长度大于2,那么我们就得去(i+1,j-1)这块区域寻找了

? ? ? ? ? ? ? ? ? ? //如果i+1=j的话,那么就说明此时的子串长度就是2,那么就说明此时的子串是回文的,那么我们直接返回true就行了

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? //每填一个dp表我们就进行一个判断的操作

? ? ? ? ? ? ? ? if(dp[i][j]==true&&j-i+1>len)//如果是回文的话并且我们的长度大于len

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? len=j-i+1;//更新我们的len的大小

? ? ? ? ? ? ? ? ? ? begin=i;//更新我们最终返回的起始位置

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return s.substr(begin,len);//直接返回从begin位置开始的len个长度的子串就行了

? ? ? ? ? ? //这个就是我们的最长长度的回文串了

? ? }

};

37.分割回文串 IV

分割回文串 IV
给你一个字符串?s?,如果可以将它分割成三个?非空?回文子字符串,那么返回?true?,否则返回?false?。

当一个字符串正着读和反着读是一模一样的,就称其为?回文字符串?。

示例 1:

输入: s = “abcbdd”
输出: true
解释:“abcbdd” = “a” + “bcb” + “dd”,三个子字符串都是回文的。

示例 2:

输入: s = “bcbddxy”
输出: false
解释: s 没办法被分割成 3 个回文子字符串。

提示:

  • 3 <= s.length <= 2000
  • s?????? 只包含小写英文字母。

我们只需要判断这三个区间是否为回文子串就行了
image.png
我们直接使用dp表保存所有的子串是否是回文的信息

class Solution

{

public:

? ? bool checkPartitioning(string s)

? ? {

? ? ? ? int n=s.size();

? ? ? ? vector<vector<bool>>dp(n,vector<bool>(n));//大小是n*n的矩阵

  

? ? ? ? for(int i=n-1;i>=0;i--)

? ? ? ? {

? ? ? ? ? ? for(int j=i;j<n;j++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(s[i]==s[j])//两个字符是相等的

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? dp[i][j]=i+1<j?dp[i+1][j-1]:true;

? ? ? ? ? ? ? ? //如果此时的i+1<j的话,那么就说明此时的子串的长度大于2,那么我们就得去(i+1,j-1)这块区域寻找了

? ? ? ? ? ? ? ? //如果i+1=j的话,那么就说明此时的子串长度就是2,那么就说明此时的子串是回文的,那么我们直接返回true就行了

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //枚举所有的第二个字符串的起始位置和结束位置

? ? ? ? for(int i=1;i<n-1;i++)//第二个字符串的区间是(1,n-2)

? ? ? ? {

? ? ? ? ? ? for(int j=i;j<n-1;j++)//这个是结束位置

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(dp[0][i-1]&&dp[i][j]&&dp[j+1][n-1])//如果满足这三个dp都是true的话,那么就说明这段回文北分为三段回文了

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? }

  

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //循环结束了,我们却没有返回,就说明没有切割成功

? ? ? ? return false;

  

? ? }

};

就是先进行正常的回文信息记录
然后再填完了dp表之后,我们再分区域进行验证操作了

38.分割回文串 II

分割回文串 II

给你一个字符串?s,请你将?s?分割成一些子串,使每个子串都是回文串。

返回符合要求的?最少分割次数?。

示例 1:

输入: s = “aab”
输出: 1
解释: 只需一次分割就可将?s 分割成 [“aa”,“b”] 这样两个回文子串。

示例 2:

输入: s = “a”
输出: 0

示例 3:

输入: s = “ab”
输出: 1

提示:

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

dp[i]表示:s[0,i]区间上的最长的子串,最少分割次数

如果(0,i)这个区间的串是回文的话,那么我们直接返回0就行了

但是如果不是回文的话
我们选择一个位置j,j的范围是0<j<=i的,就是最后一个子字符串的起始位置的下标
如果我们此时的(j,i)区间是回文的话,那么我们只需要查看(0,j-1)这个区间是否是回文的就行了
如果(j,i)区间是回文的话,那么我们直接dp[j-1]+1就行了

我们需要快速去判断(0,i)是否是回文的,(i,j)是否是回文的,所以我们这里是需要将回文的信息存放在dp中了

优化:二维dp表,将所有的子串是否是回文的信息,保存在dp表里面

初始化:将dp表中所有的值都初始化为无穷大就行了

返回dp(n-1)就行了,表示的是s[0,n-1]区间上的最长的子串,最少分割次数image.png

class Solution

{

public:

? ? int minCut(string s)

? ? {

? ? ? ? //预处理

? ? ? ? int n=s.size();

? ? ? ? vector<vector<bool>>isPal(n,vector<bool>(n));//判断是否是回文的dp表

? ? ? ? for(int i=n-1;i>=0;i--)

? ? ? ? {

? ? ? ? ? ? for(int j=i;j<n;j++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(s[i]==s[j])

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? isPal[i][j]=i+1<j?isPal[i+1][j-1]:true;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //两层循环下来之后,那么dp表里面就存放着这个字符串s的子串是否是回文的信息了

? ? ? ? //这个dp就是计算最小的切割次数的

? ? ? ? vector<int>dp(n,INT_MAX);//初始化为无穷大

? ? ? ? for(int i=0;i<n;i++)

? ? ? ? {

? ? ? ? ? ? if(isPal[0][i]==true)dp[i]=0;//如果(0,i)是回文的话,说明我们是不需要切割的

? ? ? ? ? ? else//就是说明(0,i)这个串不是回文,那么我们从中间找个点j进行遍历操作

? ? ? ? ? ? {

? ? ? ? ? ? ? ? for(int j=1;j<=i;j++)

? ? ? ? ? ? ? ? ? ? if(isPal[j][i]==true)//如果(j,i)是回文的话,我们就得计算下dp(0,j-1)的值了,那么我们就更新下最小值
? ? ? ? ? ? ? ? ? ?     //dp[j-1] 是从 0 到 j-1 的最小切割次数
                        //加 1 是因为我们要在位置 j-1 处切割一次
? ? ? ? ? ? ? ? ? ? ? ? dp[i]=min(dp[i],dp[j-1]+1);//计算下最小的分割次数

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return dp[n-1];//直接返回(0,n-1)区间上回文串切割最小次数

? ? }

};

在这段代码中,dp[i]表示从0i的子串所需的最小切割次数。初始化dpINT_MAX的目的是为了确保在计算最小切割次数时,能够找到一个最小值。

就是正常进行isPal获取我们整个串的回文信息

然后再来一个dp,这个dp[i]表示的就是(0,i)区间上回文串的最少切割次数
如果(0,i)是回文的话,那么我们直接返回0就行了,因为整个串都是回文的,我们就不需要进行切割操作了

但是如果不是的话,那么我们中间找个点j,然后j就是最后一个子串的起始位置的下标
如果此时我们的isPal[j] [i]是true的话,就说明我们j到i这段是回文的,那么我们就更新下dp[i]了,看看我们此时的是dp[i]的值小还是dp[j-1]+1的值小
dp[j-1]+1就是从 0 到 j-1 的最小切割次数,加 1 是因为我们要在位置 j-1 处切割一次

39.最长回文子序列

最长回文子序列
给你一个字符串?s?,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。

示例 1:

输入: s = “bbbab”
输出: 4
解释: 一个可能的最长回文子序列为 “bbbb” 。

示例 2:

输入: s = “cbbd”
输出: 2
解释: 一个可能的最长回文子序列为 “bb” 。

提示:

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

dp[i] [j]表示:s字符串里面[i,j]区间内的所有的子序列,最长的回文子序列的长度image.png
我们这里是不需要进行初始化的,因为我们的状态方程分的比较细
返回的是dp[0] [n-1]

class Solution

{

public:

? ? int longestPalindromeSubseq(string s)

? ? {

? ? ? ? int n=s.size();

? ? ? ? vector<vector<int>>dp(n,vector<int>(n));

  

? ? ? ? for(int i=n-1;i>=0;i--)

? ? ? ? {

? ? ? ? ? ? dp[i][i]=1;//就是dp[i][j],i和j都是1的情况,结果就是1,下面我们就不需要额外去考虑了

? ? ? ? ? ? for(int j=i+1;j<n;j++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(s[i]==s[j])

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? dp[i][j]=dp[i+1][j-1]+2;//直接考虑第三种,就是子串长度大于2,因为前面的两种情况都考虑过了

? ? ? ? ? ? ? ? ? ? //i和j位置元素相等,那么我们就去(i+1,j-1)这段区间找最长的回文序列,+2就是加上了i和j的长度

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else//就是这两个位置的数 是不相等的

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? //既然这两个位置的数不相等,那么我们就去(i+1,j)和(i,j-1)这两段区间找最大的回文序列

? ? ? ? ? ? ? ? ? ? dp[i][j]=max(dp[i+1][j],dp[i][j-1]);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

  

? ? ? ? }

? ? ? ? return dp[0][n-1];//直接返回(0,n-1)这段区间中最长的回文串子序列就行了

? ? }

};

40.让字符串成为回文串的最少插入次数

让字符串成为回文串的最少插入次数
给你一个字符串?s?,每一次操作你都可以在字符串的任意位置插入任意字符。

请你返回让?s?成为回文串的?最少操作次数?。

「回文串」是正读和反读都相同的字符串。

示例 1:

输入: s = “zzazz”
输出: 0
解释: 字符串 “zzazz” 已经是回文串了,所以不需要做任何插入操作。

示例 2:

输入: s = “mbadm”
输出: 2
解释: 字符串可变为 “mbdadbm” 或者 “mdbabdm” 。

示例 3:

输入: s = “leetcode”
输出: 5
解释: 插入 5 个字符后字符串变为 “leetcodocteel” 。

提示:

  • 1 <= s.length <= 500
  • s?中所有字符都是小写字母。

dp[i] [j]表示:s里面[i,j]区间内的子串,使他成为回文串的最小插入次数
image.png
如果s[i]!=s[j]的话,那么有两种情况,一种就是我们在左边补上一个s[j]那么就和右边的j回文上了,那么我们就处理(i,j-1)这个区间就行了
但是如果我们是在右边补上一个s[i]的话,那么我们处理的就是[i+1,j]这个区间了
因为要求的是最小的插入次数,所以我们这里是需要在两种操作中求一个min值的

我们这里是不需要进行初始化操作的,因为我们这里分的很细致了

返回值就是dp[0] [n-1]

class Solution

{

public:

? ? int minInsertions(string s)

? ? {

? ? ? ? int n=s.size();

? ? ? ? vector<vector<int>>dp(n,vector<int>(n));

  

? ? ? ? for(int i=n-1;i>=0;i--)

? ? ? ? {

? ? ? ? ? ? for(int j=i+1;j<n;j++)//我们直接从i+1的位置开始,因为当i=j的话,结果肯定是0的

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(s[i]==s[j])dp[i][j]=dp[i+1][j-1];//两个字符相等,那么我们就得看看中间的区间是否需要插入字符形成回文了

? ? ? ? ? ? ? ? //两个字符不相等,那么我们就先左边或者右边进行补齐

? ? ? ? ? ? ? ? //如果从左边补s[j]的话,那么就和j消掉了,那么我们检查的就是(i,j-1)这个区间了

? ? ? ? ? ? ? ? //反之就是(i+1,j)这个区间了

? ? ? ? ? ? ? ? else dp[i][j]=min(dp[i+1][j],dp[i][j-1])+1;//直接从这两个区间找最小值

? ? ? ? ? ? ? ? //最后+1的操作就是要么加的是左边的字符,要么加的是右边的字符

  

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return dp[0][n-1];

  

? ? }

};

还是正常的操作,先将信息存在dp表中
如果i和j两个字符相等的话,那么我们的结果就是在中间的区间(i+1,j-1)里面了

但是如果不相等的话,那么我们就得从两种补齐方式种求出最小值了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Undoom

感谢啦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
褥疮用什么药 梦见吃酒席是什么意思 常吃南瓜子有什么好处和坏处 梦见打狼是什么预兆 尿酸高饮食要注意什么
什么是香港脚 什么人容易得小脑萎缩 人巨细胞病毒是什么病 盆腔钙化灶是什么意思 什么是无期徒刑
手淫什么意思 滴度是什么意思 为什么人会流泪 有容乃大是什么意思 整夜失眠是什么病
送向日葵代表什么意思 豆浆和什么搭配最好 梦见别人结婚是什么征兆 结婚 为什么 脂肪垫是什么
查岗是什么意思hcv8jop8ns4r.cn 为什么医生都穿洞洞鞋hcv8jop1ns7r.cn 6月6什么星座hcv8jop9ns3r.cn 蛋白酶是什么东西hcv8jop7ns9r.cn 奶冻是什么hcv8jop5ns7r.cn
7月15号是什么星座hcv8jop4ns0r.cn 病毒由什么构成1949doufunao.com 感冒可以吃什么水果bjhyzcsm.com 大便颜色发黑是什么原因hcv9jop6ns1r.cn 苦荞茶适合什么人喝hcv9jop8ns3r.cn
拉肚子应该挂什么科dajiketang.com 迪士尼狗狗叫什么名字hcv8jop9ns7r.cn 合羽念什么hcv9jop5ns4r.cn 女性血热吃什么好得快1949doufunao.com 玉皇大帝姓什么hcv9jop1ns6r.cn
什么故事hcv8jop2ns9r.cn 青稞是什么hcv9jop5ns3r.cn 眼科pd是什么意思hcv7jop9ns9r.cn 家里进蝙蝠什么预兆hcv8jop8ns2r.cn 肾积水吃什么药huizhijixie.com
百度