回文分区

一、问题描述

    给定一个字符串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


梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~


猜你喜欢

转载自blog.csdn.net/qiki_tangmingwei/article/details/80423637