一、问题描述
给定一个字符串s,分区s使分区的每个子字符串都是回文。返回s的回文分区所需的最小切割。
【例子】输入: "aab"
输出: 1
回文分区[“aa”,“b”]最小可以使用1次剪切生成
二、问题分析
本题主要涉及到两个子问题:1)如何描述该动态规划的状态转移方程? 2)如何判断回文?
显然这两个子问题需要回归到同一个代码情景中,即:需要找到一个统一的方法,让这两个子问题都能得到回归。
【如何判断回文】
如果judge[i][j]=true,表示字符串从位置i到位置j是回文,那么判断条件可以写成:if( s[i]==s[j]&&judge[i+1][j-1] ) judge[i][j]=true
【如何描述转移方程】
回归到判断回文的代码情景,这里 i<= j < n; 用f(i)表示从i到n之间的最小cut数,则状态转移方程可写成:
f(i) = min( f( i ),f( j +1 ) +1 ) 即:要么cut,要么不cut,总体效果是cut值最小
三、解题算法
/***********************************************************
Author:tmw
date:2018-5-23
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define min(a,b) (a<b?a:b)
int minCut(char* s)
{
//定义回文判断的二维bool型数组,并赋初值
int n=strlen(s);
bool** judge = (bool**)malloc(n*sizeof(bool*));
int i,j;
for( i=0; i<n; i++ )
judge[i] = (bool*)malloc(n*sizeof(bool));
for( i=0; i<n; i++ )
for( j=0; j<n; j++ )
judge[i][j] = false;
//定义动态规划状态转移函数存储空间,并赋初值
int* f = (int*)malloc((n+1)*sizeof(int));
//最糟糕的情况,是每个从i位置到n-1位置都要cut一遍
for( i=0; i<=n; i++ )
f[i] = n-i-1; //f[n]=-1 为了防止当"bb"这种情况时,f[0]=1
for( i=n-1; i>=0; i-- )
{
for( j=i; j<n; j++ )
{
//i位置到j位置的回文判断
if( s[i] == s[j] && ( j-i<=1 || judge[i+1][j-1]) )
{
judge[i][j] = true;
f[i] = min(f[i],1+f[j+1]);
}
}
}
return f[0];
}四、执行结果
accept
梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~
本文介绍了一种解决字符串回文分区问题的算法,通过动态规划方法寻找字符串的最小分割次数,使得每个子串都是回文。文章详细阐述了状态转移方程及回文判断条件,并提供了完整的C语言实现。
281

被折叠的 条评论
为什么被折叠?



