zoukankan      html  css  js  c++  java
  • 【待字闺中】最少插入字符

    题目

    给定字符串,可以通过插入字符,使其变为回文。求最少插入字符的数量。

    例如:

    1.ab最少插入1个字符,变为*b*ab

    2.aa最少插入0个字符

    3.abcd最少插入3个字符,*dcb*abcd

    思路:

    给出递归的解法,发现重复的子问题,然后改进算法,用动态规划。

    https://gist.github.com/sing1ee/a97b21fd50a0ae90e62b#rd

    这个题目的分析思路,和前面两期是非常相似的:给出递归的解法,发现重复的子问题,改进为动态规划的解法,这是一个分析的过程,待同学们比较熟悉时候,可以直接给出动态规划的解决方案,就很好了。

    这个题目,递归该如何解呢?给定一个字符串str,长度为n,怎么插入最少的字符,是的字符串变为回文呢?插入最少的字符,就是要尽量利用原来的字符,在原字符串str中,尽量利用更多能够匹配的字符。怎么对这个问题进行分解呢?考虑str字符串整体:

    1. 如果str[0]==str[n-1],则问题转变为求str[1,n-2],插入最少字符,得到回文
    2. 如果str[0]!=str[n-1],则需要插入一个字符要么和str[0]相同,要么和str[n-1]相同,
      1. 如果和str[0],则转变为str[1,n-1],插入最少字符,得到回文
        1. 如果和str[n-1],则转变为str[0,n-2],插入最少字符,得到回文

    上面的第2种情况中,需要取两个值最小值。则完成了问题的分解,并且,基本情况也分析完全,则有递归式为:

    fmi(str, l, h) = (str[l] == str[h]) ? fmi(str, l+1, h-1) : (min(fmi(str, i+1, h), fmi(str,l, h-1))+1)

    通过上面的式子,有经验的、熟练的同学,很直接的就能看出来,存在重复的子问题,这就意味着,我们可以讲子问题的解缓存使用。如果,没有直接能够看出来的同学们,还是可以按照我们之前的方法,把递归树画出来吧,那样更加一目了然。

    那么,这个题目该如何用动态规划的解决呢?如何重复利用子问题的解呢?似乎有些不那么直接。但其实也是于规律可循的。上面的递归式,是从字符串的两边,想中间移动递归,根据动态规划解决问题的思想,我们先解决子问题,再重复利用子问题,就是要从内向外解决,大家还记得回文子串判断的那个题目么,动态规划解法的外层循环是子串的长度,这个题目也是类似的。示例代码如下:

    int fmiDP(char str[], int n)
    {
        //二维数组保存子问题的解,table[i][j]表示str[i,j]转换为回文,需要插入的最少字符数。
        int table[n][n], l, h, gap;
    
        memset(table, 0, sizeof(table));
    
        // 外层循环,gap从小到大
        for (gap = 1; gap < n; ++gap)
            for (l = 0, h = gap; h < n; ++l, ++h)
                table[l][h] = (str[l] == str[h])? table[l+1][h-1] :
                              (min(table[l][h-1], table[l+1][h]) + 1);
        return table[0][n-1];
    }
    

    这个题目在使用动态规划解的时候,略有点儿绕,不太好想到如何利用子问题的解。这个没有更好的方法,就是多多积累,遇到问题勤于思考,举一反三。

    【分析完毕】

  • 相关阅读:
    oralce 11g data guard
    oracle的锁与并发机制
    10 个MySQL数据库备份教程推荐
    Linux环境下用exp备份Oracle数据表并导入的脚本
    使用Oracle 10g的Logminer挖掘日志
    ORACLE查询表最近更改的数据
    如何监控oracle的索引是否使用
    看 淡 一切 生 命 只 是 个 过 程
    Java数组声明、创建、初始化
    Linux建立FTP的方法
  • 原文地址:https://www.cnblogs.com/karcylee/p/3952622.html
Copyright © 2011-2022 走看看