字符串问题---添加最少字符使字符串整体都是回文字符串
来源:互联网 发布:高斯模糊算法 cpu消耗 编辑:程序博客网 时间:2024/05/22 06:10
【题目】
给定一个字符串str,如果可以在str的任意位置添加字符,请返回在添加字符最少的情况下,让str整体都是回文字符串的结果。
【进阶题目】
给定一个字符串str,再给定str的最长回文子序列字符串strlps,请返回在添加字符最少的情况下,让str整体都是回文字符串的一种结果。进阶问题比原问题多了一个参数,请做到时间复杂度比原问题的实现低。
【基本思路】
原问题。首先考虑,如果可以在str的任意位置添加字符,最少需要添加几个字符就可以让str整体都是回文字符串。这个问题可以使用动态规划解决。如果str的长度为N,生成N×N的dp矩阵,dp[i][j]的含义是子串str[i…j]最少添加几个字符可以使str[i…j]整体都是回文串。dp[i][j]的求法如下:
如果i == j,说明此时只有一个字符,本身就是回文串,dp[i][j] = 0。
如果str[i…j]有两个字符,如果这个字符相同dp[i][j] = 0。否则dp[i][j] = 1。
- 如果str[i…j]多于两个字母,如果str[i] == str[j]。则dp[i][j] = dp[i+1][j-1]。否则,dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1。为什么呢?举例说明,假设str = “ABC”,可以先将“BC”变成回文串“BCB”,然后在末尾加“A”,也可以先将“AB”变成回文串“ABA”,然后在最前面加“C”。即可以先处理str[i+1…j]然后末尾加str[i],也可以先处理str[[i…j-1]然后开头加str[j]。
接下来介绍如何根据dp矩阵,求在添加字符最少的情况下,让str整体都是回文字符串的一种结果。首先,dp[0][N-1]的值代表整个字符串最少需要添加几个字符,所以,如果最后的结果记为字符串res,res的长度为 N + dp[0][N-1],然后依次设置res左右两头的字符。具体过程如下:
如果str[i] == str[j],那么str[i…j]变成回文串的最终结果为 str[i] + str[i+1][j-1]变成回文串的结果 + str[j],此时res的左右两头字符为str[i],然后根据str[i+1][j-1]和矩阵dp确定res的中间部分。
如果str[i] != str[j],判断dp[i][j-1]和dp[i+1][j]哪个小,如果dp[i][j-1]小,那么str变成回文串的结果为 str[j] + str[i][j-1]变成回文串的结果 + str[j],此时res左右两头的字符为str[j],然后根据str[i][j-1]和矩阵dp确定res的中间部分。如果dp[i+1][j]小,过程同上。
下面是使用python3.5实现的代码
#添加最少字符使字符串整体都是回文字符串#原问题def getPalindrome(str1): def getdp(str1): dp = [[0 for i in range(len(str1))] for j in range(len(str1))] for j in range(1, len(str1)): dp[j-1][j] = 0 if str1[j-1] == str1[j] else 1 for i in range(j-2, -1, -1): if str1[i] == str1[j]: dp[i][j] = dp[i+1][j-1] else: dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1 return dp if str1 == None or len(str1) < 2: return str1 dp = getdp(str1) res = [0 for i in range(len(str1)+dp[0][len(str1)-1])] i = 0 j = len(str1) - 1 resl = 0 resr = len(res) - 1 while i <= j: if str1[i] == str1[j]: res[resl] = str1[i] res[resr] = str1[j] i += 1 j -= 1 elif dp[i+1][j] < dp[i][j-1]: res[resl] = str1[i] res[resr] = str1[i] i += 1 else: res[resl] = str1[j] res[resr] = str1[j] j -= 1 resl += 1 resr -= 1 return ''.join(res)
进阶问题。假设str的长度为N,strlps的长度为M,则整体回文串的长度为2×N - M。整个过程类似 “剥洋葱”。代码如下:
#补充问题def getPalindrome2(str1, strlps): if str1 == None or len(str1) == 0 or strlps == None or len(strlps) == 0: return res = [0 for i in range(2*len(str1)-len(strlps))] lstr = 0 rstr = len(str1)-1 llps = 0 rlps = len(strlps)-1 lres = 0 rres = len(res)-1 while llps <= rlps: temp1 = lstr temp2 = rstr while str1[lstr] != strlps[llps]: lstr += 1 while str1[rstr] != strlps[rlps]: rstr -= 1 for i in range(temp1, lstr): res[lres] = str1[i] res[rres] = str1[i] lres += 1 rres -= 1 for i in range(temp2, rstr, -1): res[lres] = str1[i] res[rres] = str1[i] lres += 1 rres -= 1 res[lres] = str1[lstr] res[rres] = str1[rstr] lstr += 1 rstr -= 1 lres += 1 rres -= 1 llps += 1 rlps -= 1 return ''.join(res)
- 添加最少的字符使整体字符串都是回文字符串
- 字符串问题---添加最少字符使字符串整体都是回文字符串
- 牛客面试算法题精讲【个人总结】- 添加最少字符以使字符串整体都是回文字符串
- 添加最少字符使成为回文字符串
- 添加最少字符数构成使字符串构成回文
- 添加最少的字符使字符串成为回文
- DP问题---添加字符把字符串变为回文字符串
- 插入最少的字符使字符串成为回文
- 删除最少字符 使字符串成为回文串
- 插入最少字符使字符串回文(LCS,DP)
- 插入最少的字符使字符串成为回文串
- 添加字符成为回文字符串
- 给定字符串,删除最少的字符,使剩下的字符串成为回文串
- 每日AC- 美团 -- 直方图中最大矩形 与最少字符使字符串变成回文字符串
- 一个字符串要变成回文串的需要添加的字符最少个数
- 回文字符串 的添加问题
- 插入最少的字符使字符串成为回文串 <最长公共子序列 + 回文>
- 源字符串插入最少字符生成回文串
- socketIO服务器,安卓,js端使用代码
- 几篇有关CSS的文章
- 解决maven删除和重新安装的问题
- #leetcode#130. Surrounded Regions
- 【codeforce-510B】fox and two dots
- 字符串问题---添加最少字符使字符串整体都是回文字符串
- 利用fir.im提供的api接口实现android apk自动更新和手动更新
- URL中“#” “?” &“”号的作用
- spring boot banner的设置
- HDU6154 CaoHaha's staff(规律,2017中国大学生程序设计竞赛
- JMeter安装步骤
- Excel要不要“引”
- UVA
- collection和collections的区别,以及一些工具类数组与集合转换