最长回文子串之动态规划(C语言版)

这个动态规划的方法是在暴力的基础上改良而来的,但怎么说呢!我写出来的结果也不是很好,空间和时间都没有中心扩展方法好

最长回文子串之动态规划法

  • 动态规划分析
  • 代码过程表述(结合代码看)
  • 代码和成果展示

动态规划分析

  • 如何想到的
    当然,你要是一个练题练得久了的大佬,自然就知道该采用动态规划,这就是 学霸手感 。不过再牛X也是从小白过来的,且听我娓娓道来,首先普通人先想到的是暴力法,(不懂的可以搜一下这道题的暴力解法或者看一下我关于此法的文章),在暴力法中,你会发现很多地方你其实可以避免再次计算的,只要把这段子串是不是回文给几下来。例如:ababa 你暴力法验证bab时,你算了一边bab是不是回文串,在你验证babab时,你是不是还要看看它里面的bab是不是回文串,这样你就重复算了,于是 于是 于是。。。。。聪明的一休光头程序员想到了我用什么东西给标志一下bab已经是回文串了,下次再遇到ababa时,一看bab 标志 ,欧克,再看bab左边一个和右边相等 那这个ababa也是回文串,标志给戴上。

  • 形式化解释
    最长回文子串之动态规划(C语言版)_第1张图片

代码过程表述(结合代码看)

1.建立和初始化一个布尔类型的表格,用来存放中间结果
2.建立两个整型变量,一个用来存放回文开始位置,一个存放回文长度
3 以abcabcda为例,先把(i,j):(0.0)(1.1)(2.2)。。。给提前给填写了
4.开始正式填表
4.1 循环填表,整个过程填(0.1)然后(0.2)(1.2)然后(0.3)(1.3)(2.3)…
注意 这个过程要理解一下。按照上面的例子,推一下就知道为什么是这个顺序了,只可意会不可言传啊

代码和成果展示



char * longestPalindrome(char * s){
//这一次采用动态规划的方法来做
//分析:动态规划中的特殊点,就是当只有一个字母时,肯定是回文。
//第二点就是只有两个字母或三个字母时,回文的状态方程是不适用的
//针对这两点可以分开来,用if else 语句分别来判断
int length =(int)strlen(s);
if(length==0||length==1)
return s;

bool table[1000][1000];
//bool ** table=(bool**)malloc(length*sizeof(bool*));//动态规划常用的表
for(int i=0;i<length;i++)
{
   // table[i]=(bool*)malloc(length*sizeof(bool));
 table[i][i]=true;
}
int start=0;int len=1;//字符开始的位置和长度
for(int j=1;j<length;j++)//方向采用的是自上而下
{
    for(int i=0;i<j;i++)
    {
        if(s[i]==s[j])
        {
            if(j-i<3)//这个有一个,两个,三个,字母的时候,根本不用看里面,只要s[i]==s[j]就行
            {
                table[i][j]=true;
            }
           else 
               table[i][j]=table[i+1][j-1];
        }
        else
        table[i][j]=false;

        if(table[i][j]&&(j-i+1)>len)
        {
            start = i;
            len =j-i+1;
        }
    }
}

s[start+len]='\0';
return(s+start);
}


执行用时 :
120 ms
, 在所有 C 提交中击败了
51.08%
的用户
内存消耗 :
8.1 MB
, 在所有 C 提交中击败了
22.22%
的用户

你可能感兴趣的:(算法)