题解 | #最小编辑代价#

最小编辑代价

http://www.nowcoder.com/practice/05fed41805ae4394ab6607d0d745c8e4

题目要求s1 通过增、删、替换的方式以最小的操作数变成 s2,即两个字符串比较求极值,由两个字符串和比较等特点分析应该可采用递归的方式的处理,即 func(s1[i], s2[j]) 对两个字符串的每个字符进行比较,直到 i、j 取完,当 s1[i] == s2[j] 直接递归 s1[i - 1] s2[j - 1] 而当 s1[i] != s2[j] 时,则有三种方式可选,即三条路径,存在重叠子问题,可采用动态规划的方式求解

  1. 定义 dp 数组,因为是两个字符串,则定义二维数组 dp[i][j] 表示 s1[:i + 1] 变成 s2[:j + 1] 的最小操作数
  2. 定义 base case, dp[0][i] 表示 s1 = '' 时变成 s2 的最小步数,即每次都增加一个字符, dp[i][0] 表示 s2 = '' 时 s1 变成 s2的最小步数,即每次都减少一个字符
  3. 确定状态转移方程, 即求解 dp[i][j] 的生成过程
    (1) s1[i] == s2[j] 时,dp[i][j] = dp[i - 1][j - 1] 不需要额外操作
    (2) s1[i] != s2[j] 时,dp[i][j] 可以从三个状态转移
    1) dp[i - 1][j] + dc 表示 s1[:i] 匹配 s2[:j + 1] 此时 s1[i] 多余删除
    2)dp[i][j - 1] + ic 表示 s1[:i + 1] 匹配 s2[:j] 此时插入 s2[j]
    3) dp[i - 1][j - 1] + rc 表示 s1[:i] 匹配 s2[:j] 替换 s1[i] 和 s2[j]的值
    这样自底向上的求出s1变成s2的最小操作数
    代码:
    class Solution:
     def minEditCost(self , str1 , str2 , ic , dc , rc ):
         # write code here
         dp = [[0 for _ in range(len(str2) + 1)] for _ in range(len(str1) + 1)]
         for i in range(1, len(str2) + 1):
             dp[0][i] = dp[0][i - 1] + ic
         for i in range(1, len(str1) + 1):
             dp[i][0] = dp[i - 1][0] + dc
         for i in range(1, len(str1) + 1):
             for j in range(1, len(str2) + 1):
                 if str1[i - 1] == str2[j - 1]:
                     dp[i][j] = dp[i - 1][j - 1]
                 else:
                     dp[i][j] = min(dp[i][j - 1] + ic, dp[i - 1][j] + dc, dp[i - 1][j - 1] + rc)
         return dp[-1][-1]
全部评论

相关推荐

04-13 20:21
门头沟学院 Java
点赞 评论 收藏
分享
03-26 13:04
已编辑
电子科技大学 算法工程师
xiaowl:你这个简历“条目上”都比较有深度性,但是实际上面试官又没法很好的评估你是怎么达到很多看上去很厉害的结果的。要避免一些看上去很厉害的包装,比如高效的内存复用策略的表达,如果仅是简单的一些内存共享机制,而且面试上也没有深挖的空间,就不要这样表达。比如,工程化模式本质上可能就是定义了一些abstract class,那也就没特别多值得讲的内容。建议简历上应该侧重那些你花了大量时间和精力解决、研究的问题,不要过分追求“丰富”,而是关注在技术深入度、问题解决能力的表现上。
没有实习经历,还有机会进...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务