字符串问题---回文最小分割数
2017-08-27 13:21
288 查看
【题目】
给定一个字符串str,返回把str全部切成回文子串的最小分割数。
【举例】
str = “ABA”,str本身就是回文串,返回0.
str = “ACDCDCDAD”,最少需要切两次变成3个回文子串,所以返回2.
【基本思路】
本题是一个经典的动态规划的题目。定义动态规划数组dp,dp[i]的含义是子串str[0…i]至少需要切割几次,才能把str[0…i]全部切成回文子串。那么dp[len-1]就是最后的结果。
从左往右依次计算dp[i]的值,i 初始为0,具体计算过程如下:
1、假设 j 处在 0 到 i 之间,如果str[j…i]是回文串,那么dp[i]的值可能是dp[j-1] + 1,其含义是在str[0…i]上,既然str[j…i]是回文串,那么它可以自己作为一个分割的部分,剩下的部分str[0…j-1]继续做最经济的分割,也就是dp[j-1]的值。
2、根据步骤1的方式,让 j 在 i 到 0 的位置上枚举,那么所有可能中最小值就是dp[i]的值,即dp[i] = min{dp[j-1]+1 (0<= j <= i,且str[j…i]必须是回文串)}。
3、如何快速方便的判断str[j…i]是否为回文串?
1)定义一个二维数组p,如果p[j][i]为True,表示str[j…i]是回文串,否则不是。在计算dp过程中,希望能够同步、快速的计算出矩阵p。
2)p[j][i]如果为True,一定来自以下三种情况:
<1> str[j][i]由一个字符组成
<2> str[j][i]由两个字符组成且两个字符相等
<3> str[j][i]由多个字符组成,str[j] == str[i]且p[j+1][i-1] == True。
3)在计算dp数组的过程中,位置i是从左向右依次计算的。而对于每一个i来说,又依次从 i 位置向左遍历所有的位置,以此来决策dp[i]。所以对于p[j][i]来说,p[j+1][i-1]一定已经计算过。
从后往前遍历str也是可以的,原理同上,详情见代码,这么做下标理解起来可能更容易一点。
下面是使用python3.5实现的代码。
给定一个字符串str,返回把str全部切成回文子串的最小分割数。
【举例】
str = “ABA”,str本身就是回文串,返回0.
str = “ACDCDCDAD”,最少需要切两次变成3个回文子串,所以返回2.
【基本思路】
本题是一个经典的动态规划的题目。定义动态规划数组dp,dp[i]的含义是子串str[0…i]至少需要切割几次,才能把str[0…i]全部切成回文子串。那么dp[len-1]就是最后的结果。
从左往右依次计算dp[i]的值,i 初始为0,具体计算过程如下:
1、假设 j 处在 0 到 i 之间,如果str[j…i]是回文串,那么dp[i]的值可能是dp[j-1] + 1,其含义是在str[0…i]上,既然str[j…i]是回文串,那么它可以自己作为一个分割的部分,剩下的部分str[0…j-1]继续做最经济的分割,也就是dp[j-1]的值。
2、根据步骤1的方式,让 j 在 i 到 0 的位置上枚举,那么所有可能中最小值就是dp[i]的值,即dp[i] = min{dp[j-1]+1 (0<= j <= i,且str[j…i]必须是回文串)}。
3、如何快速方便的判断str[j…i]是否为回文串?
1)定义一个二维数组p,如果p[j][i]为True,表示str[j…i]是回文串,否则不是。在计算dp过程中,希望能够同步、快速的计算出矩阵p。
2)p[j][i]如果为True,一定来自以下三种情况:
<1> str[j][i]由一个字符组成
<2> str[j][i]由两个字符组成且两个字符相等
<3> str[j][i]由多个字符组成,str[j] == str[i]且p[j+1][i-1] == True。
3)在计算dp数组的过程中,位置i是从左向右依次计算的。而对于每一个i来说,又依次从 i 位置向左遍历所有的位置,以此来决策dp[i]。所以对于p[j][i]来说,p[j+1][i-1]一定已经计算过。
从后往前遍历str也是可以的,原理同上,详情见代码,这么做下标理解起来可能更容易一点。
下面是使用python3.5实现的代码。
#回文最小分割数 #从前往后遍历 def minCut(str1): if str1 == None or str1 == "": return 0 N = len(str1) p = [[False for i in range(N)] for j in range(N)] dp = [0 for i in range(N)] for i in range(N): dp[i] = sys.maxsize for j in range(i, -1, -1): if str1[j] == str1[i] and (i-j < 2 or p[j+1][i-1]): p[j][i] = True dp[i] = min(dp[i], 0 if j-1 == -1 else dp[j-1] + 1) return dp[-1] #从后往前遍历 def minCut2(str1): if str1 == None or str1 == "": return 0 N = len(str1) dp = [0 for i in range(N)] p = [[False for i in range(N)] for j in range(N)] for i in range(N-1, -1, -1): dp[i] = sys.maxsize for j in range(i, N): if str1[i] == str1[j] and (j-i < 2 or p[i+1][j-1]): p[i][j] = True dp[i] = min(dp[i], 0 if j+1 == N else dp[j+1] + 1) return dp[0]
相关文章推荐
- 求回文字符串的最小分割
- java 竖线分割字符串的问题
- 51nod 1092 回文字符串 dp问题
- 回文字符串问题
- 分割成回文需要的最小分割数 Palindrome Partitioning II @LeetCode
- 字符串分割成字串都是回文
- java 竖线分割字符串的问题
- java字符串分割问题
- 制定字符分割字符串(逻辑上还有一定问题)
- java关于split分割字符串问题
- 回文字符串问题
- Java split用竖线分割字符串的问题
- 【DP】回文的最小分割数2
- 《编程之美》- 3.3 - 计算字符串相似度 即 最小编辑距离问题
- 关于split分割字符串,空结果不能得到的问题
- 数据结构常见问题(二)利用栈和队列判断字符串是否是回文
- 动态规划的思想来求解字符串分割问题
- C#分割(Split)字符串问题
- Java split用竖线分割字符串的问题
- 字符串分割与质数问题