双侧颈部淋巴结可见是什么意思| 红斑狼疮复发的症状是什么| 对头是什么意思| 前列腺穿刺是什么意思| 微信头像用什么好| 中耳炎什么症状| 天蝎座和什么星座配| 塞翁失马什么意思| 什么叫hp感染| 女人来月经吃什么好| 鼻窦炎首选什么抗生素| bebe是什么牌子| 一只什么| 1120是什么星座| 1.7号是什么星座| 血常规是什么| 双离合是什么意思| 降血糖吃什么菜| 为什么手心总是出汗| 为情所困是什么意思| 冰释前嫌是什么意思| 身心健康是什么意思| 为什么月经期有性冲动| 女性朋友生日送什么礼物好| 八字不合是什么生肖| 肾尿盐结晶是什么意思| 热鸡蛋滚脸有什么作用| 癌胚抗原是什么意思| 面瘫吃什么药好得快| 逸搏心律什么意思| 污蔑是什么意思| 毛子是什么意思| 半夜腿抽筋是什么原因| 甘油脂肪酸酯是什么| 拉泡泡屎是什么原因| 胖子从12楼掉下来会变什么| 文武双全是什么意思| 中暑不能吃什么| 每天起床口苦口臭是什么原因| 中性粒细胞计数偏高是什么意思| 蓝精灵是什么药| 香蕉皮擦脸有什么作用与功效| 学富五车是什么意思| 今日什么冲什么生肖| 绛紫色是什么颜色| 什么是植物蛋白| 畸胎瘤是什么| 皮肤变白是什么原因| 龙的三合生肖是什么| 为什么会做梦中梦| 球蛋白偏低是什么意思| gap是什么品牌| 嘴唇裂口是什么原因| 什么情况下需要做活检| 非典是什么| 生姜水洗头有什么好处| 右腹疼是什么原因| faleda是什么牌子的手表| 喜用神什么意思| 白带豆腐渣状用什么药| 国印贵人是什么意思| 2026年是什么生肖年| 超滤是什么意思| 子母环是什么形状图片| 阴阳两虚吃什么中成药| 考护师需要什么条件| 梦见偷菜是什么意思| 低血压适合吃什么食物| 空腹喝牛奶为什么会拉肚子| 肠炎能吃什么食物| 宫颈潴留性囊肿是什么| 心境什么意思| 抠鼻表情是什么意思| 胆囊壁毛糙什么意思| 眼睛疼吃什么药效果最好| 什么时间种白菜| 怀孕了不想要最好的办法是什么| 鼻子无故出血什么原因| 属猪适合佩戴什么饰品| 下腹痛挂什么科| 什么的雪花| 黔驴技穷的意思是什么| 异地办理临时身份证需要什么材料| 艾滋病有什么症状| 湿热内蕴吃什么中成药| 百什么百什么| 皮肤角质化用什么药膏| 手机的英文是什么| peek是什么材料| oce是什么牌子| 胃ct能检查出什么病| 什么茶刮油| 瑄字五行属什么| 王几是什么字| 什么叫同理心| 癫狂是什么意思| 1985年属牛的是什么命| 焖子是什么做的| ab面是什么意思| 美国为什么不敢动朝鲜| 什么好像什么造句| 膝盖发热是什么原因| 狗毛对人体有什么危害| 男生为什么喜欢摸胸| 参谋长是什么级别| 肌酐高什么原因引起的| 武则天为什么立无字碑| 严重失眠有什么方法| 呆若木鸡的意思是什么| 口疮反复发作什么原因| 肌肉溶解是什么意思| 医疗行业五行属什么| 盐是什么| 尿结石挂什么科| 停车坐爱枫林晚的坐是什么意思| 飞吻是什么意思| 半夜三更是什么生肖| 吃莲子有什么好处| 乐高为什么这么贵| 玩是什么意思| 什么是代偿| 月加亏念什么| 命硬的人有什么特征| 拍胸片挂什么科室| 带状疱疹可以吃什么水果| 体毛旺盛是什么原因| 48岁属什么| 下午17点是什么时辰| 阳痿早泄挂什么科| 同工同酬是什么意思| 女性盆腔炎什么症状| 刚愎自负是什么意思| 吃什么可以降糖| ost是什么意思| 湿热内蕴吃什么中成药| 眼白浑浊是什么原因| 为什么一热脸就特别红| 女人外阴瘙痒用什么药| 12356是什么电话| 溥仪和慈禧什么关系| 梦见老牛是什么意思| 什么降血脂效果最好的| 菲林是什么| 高血压有什么危害| 女人脸色发黄吃什么补得最快| 为什么会长牙结石| 榴莲为什么那么贵| graff是什么牌子| jones是什么意思| 小雪时节吃什么| 促狭一笑是什么意思| 7月17日是什么星座| 江字五行属什么| 梦见捉蛇是什么意思| 蝼蛄是什么动物| 掉头发吃什么| 农历六月六是什么节日| 鼻涕有血丝是什么原因| 新生儿出院回家有什么讲究| 名字是什么意思| 车加昆念什么| 酒花浸膏是什么| 皮肤容易过敏是什么原因| 身份证拍照穿什么衣服| 巴西龟吃什么食物| 喝蒲公英茶有什么作用| 胃疼有什么办法缓解| 午餐吃什么好又能减肥| 恋爱是什么感觉| 吃什么减肚子上的赘肉最快| 镇党委副书记是什么级别| 性生活频繁有什么危害| 怕热爱出汗是什么原因| 白细胞高说明什么| 非钙化斑块是什么意思| 霍金是什么病| 1989年出生的是什么命| 9是什么意思| 梦见穿新衣服是什么意思| 肺炎吃什么药效果好| 黄花菜什么人不能吃| 胃病喝什么茶养胃| 奇货可居是什么意思| 0元购是什么意思| 白气是什么物态变化| 卡介苗预防什么病| 什么时候减肥效果最快最好| 海苔是什么| 风雨雷电代表什么生肖| 心神不定是什么生肖| 头发发黄是什么原因| 金牛座是什么星座| 悦五行属什么| 非即食是什么意思| 化生子是什么意思| abi是什么意思| 抽象是什么意思| l代表什么单位| 男人尿频是什么原因| 手掌上的三条线分别代表什么| 肠胃不好拉肚子吃什么药| 阿胶糕适合什么人吃| 考试穿什么颜色最吉利| 胃有灼热感是什么原因| 3月29号是什么星座| 右手手指头麻木是什么病的前兆| fk是什么意思| cn是什么意思二次元| 非淋菌性尿道炎吃什么药最好| 昆明有什么特产| ctc是什么| 什么人容易老年痴呆| 接待是什么意思| 土命和什么命最配| 贝壳吃什么食物| 百年灵手表什么档次| 摸摸唱是什么意思| 右肋骨下方是什么器官| 感染幽门螺杆菌吃什么药| 吃茄子有什么坏处| pretty是什么意思| 72年属什么的生肖| 伊朗是什么派| 宝宝拉肚子吃什么药好得快| 卡姿兰是什么档次| 吃什么补白蛋白最快| 狐臭是什么引起的| 一级甲等医院是什么意思| 羞羞是什么意思| 宽字五行属什么| 白泽是什么| 一般细菌培养及鉴定是检查什么| 打呼噜挂什么科室| 心悸吃什么中成药| c13阴性是什么意思| 卖萌是什么意思| 付诸东流是什么意思| 公鸡蛋是什么| ppe是什么| 床塌了有什么预兆| 汗疱疹用什么药膏最好| 故宫什么时候建的| 蓝莓和什么不能一起吃| 化疗能吃什么水果| 严什么的态度| 血氧饱和度低于90有什么危害| 阿里巴巴是干什么的| 缺钾有什么症状| 脚上真菌感染用什么药| 天气热吃什么解暑| 为什么喜欢你| 泡泡棉是什么面料| 检查肝脏挂什么科| 样板间是什么意思| 松鼠尾巴像什么| 什么菜炒肉好吃| 腹部胀疼是什么原因| 满日是什么意思| 山东特产是什么生肖| 开胸手术吃什么补元气| 没有痔疮大便出血是什么原因| sf什么意思| 巴氏征阳性是什么意思| 吃茄子对身体有什么好处| 百度

赣京绿色金融合作推介会暨项目签约仪式在京举行

百度 进一步影响了市场集中度,不易形成规模经济。

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、付费专栏及课程。

余额充值
金骏眉是什么茶类 物竞天择什么意思 白痰吃什么药 大饼是什么意思 酒不醉人人自醉是什么意思
什么病会引起牙疼 什么年树木 trab抗体偏高代表什么 颈椎病吃什么药最好效果 不吃肉对身体有什么影响
尖货是什么意思 肠道感染吃什么消炎药 跟腱是什么 腺样体是什么 办身份证要带什么
月亮象征着什么 非常的近义词是什么 食管裂孔疝是什么病 嗔恨是什么意思 生脉饮适合什么人群
森达属于什么档次的鞋wmyky.com 香蕉有什么好处hcv7jop6ns4r.cn 低密度脂蛋白是什么意思fenrenren.com 牛肚是什么hcv9jop4ns7r.cn 萎缩性胃炎用什么药最好hcv7jop4ns7r.cn
为什么一照相脸就歪了hcv8jop4ns6r.cn 很轴是什么意思hcv8jop7ns0r.cn 卤水点豆腐是什么意思kuyehao.com 喝红枣水有什么好处和坏处hcv9jop5ns4r.cn 女人喝咖啡有什么好处和坏处onlinewuye.com
脑供血不足挂什么科hcv8jop2ns8r.cn 女贞子是什么hcv8jop0ns2r.cn 劲爆是什么意思hcv9jop0ns4r.cn 什么是扦插hcv7jop6ns9r.cn 蛟龙是什么意思hcv8jop6ns9r.cn
赶尽杀绝什么意思hcv7jop6ns1r.cn 女性尿路感染什么原因引起的96micro.com 证监会是干什么的hcv8jop2ns8r.cn 达芬奇是干什么的hcv8jop5ns2r.cn 气短气喘吃什么药hcv8jop3ns8r.cn
百度