算法细节系列(14):动态规划之字符串处理
来源:互联网 发布:淘宝能买哪些虚拟产品 编辑:程序博客网 时间:2024/05/21 22:10
算法细节系列(14):动态规划之字符串处理
详细代码可以fork下Github上leetcode项目,不定期更新。
题目均摘自leetcode:
- 392 Is Subsequence
- 516 Longest Palindromic Subsequence
- 072 Edit Distance
392.Is Subsequence
水题,不一定要使用DP,但既然此章节关于DP,咱们就用DP解。
public boolean isSubsequence(String s, String t){ if (s.isEmpty()) return true; int n = s.length(); boolean[] isSeq = new boolean[n]; int index = 0; for (int i = 0; i < t.length(); i++){ if (s.charAt(index) == t.charAt(i)){ isSeq[index++] = true; if (isSeq[n-1]) return true; } } return isSeq[n-1]; }
516. Longest Palindromic Subsequence
一道区间DP,更新没什么好说的,但需要注意两个for循环的遍历顺序。递推式:
//dp[j][i] 表示在区间[j,i]之间的最长回文,可断s[j] == s[i]: dp[j][i] = dp[j+1][i-1] + 2;//没有最新的回文生成,所以沿用旧的回文长度s[j] != s[i]: dp[j][i] = Math.max(dp[j+1][i],dp[j][i-1]);
public int longestPalindromeSubseq(String s) { int n = s.length(); int[][] dp = new int[n][n]; char[] c = s.toCharArray(); for (int i = 0; i < n; i++) { dp[i][i] = 1; for (int j = i-1; j >= 0; j--) { if (c[j] == c[i]) { dp[j][i] = dp[j + 1][i - 1] + 2; } else { dp[j][i] = Math.max(dp[j+1][i], dp[j][i-1]); } } } return dp[0][n-1]; }
72. Edit Distance
比较抽象的一道题,要求两个字符串的最短编辑距离。
dp[i][j] : 表示word1[0,i)和word2[0,j)的最短编辑距离如:dp[1][0] = 1, "a"," "dp[1][1] = ?, "a","a" 相等,? = 0,"a","b" 不相等, ? = 1初始化:(字符串为空串的情况下,最短编辑距离等于字符串长度)dp[i][0] = i;dp[0][j] = j;递推式:dp[i][j] = dp[i-1][j-1]; if word1[i] == word2[j];dp[i][j] = min(dp[i-1][j] + dp[i][j-1] + dp[i-1][j-1]) + 1; if word1[i] != word2[j];举个简单的例子说明它们的含义:(word1不去操作,所有操作在word2上进行)word1 : "a"word2 : "ab"dp[0][0] = 0; " " == " "dp[0][1] = 1; edit -> "&a", "&b"dp[0][2] = 2; edit -> "&&a", "&&"dp[1][1] = dp[0][0] = 0; "a" == "a", no editdp[1][2] = ?; "a" != "b"存在三种情况:a. dp[1][2] = dp[0][1] = 2; "&a","&b" edit -> "&a","&a"我们已知道了dp[0][1]表示为"&a","&b",所以只能进行替换操作。即:dp[i][j] = dp[i-1][j-1]dp[i-1][j-1]表示了最短编辑距离,也可以表示成两字符串经过编辑后已然相等,而此时为了能够更新到dp[i][j],只能对word2的第j个字符做替换操作。b. dp[1][2] = dp[1][1] = 1; "a","ab" edit -> "a","a"即:dp[i][j] = dp[i][j-1]显然,dp[1][1] = 0,没有操作。而此时为了能够更新到dp[i][j],让两字符串相等,只能删除word2的第j个字符。c. dp[1][2] = dp[0][2] = 3; "&&a","&&" edit -> "&&a","&&a"即:dp[i][j] = dp[i-1][j];同理,dp[0][2] = 2, 说明了word2 = "&&",而为了能够更新到dp[i][j],只能添加到第j个字符后。最后在这三种操作中,取最小的即可。
注意:”&”空字符串占位符,所以有”&&” = “&”,且我们所有操作只针对一个对象。代码如下:
public int minDistance(String word1, String word2) { int m = word1.length(); int n = word2.length(); int[][] cost = new int[m + 1][n + 1]; for (int i = 0; i <= m; i++) cost[i][0] = i; for (int i = 1; i <= n; i++) cost[0][i] = i; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (word1.charAt(i) == word2.charAt(j)) cost[i + 1][j + 1] = cost[i][j]; else { int a = cost[i][j]; int b = cost[i][j + 1]; int c = cost[i + 1][j]; cost[i + 1][j + 1] = a < b ? (a < c ? a : c) : (b < c ? b : c); cost[i + 1][j + 1]++; } } } return cost[m][n]; }
0 0
- 算法细节系列(14):动态规划之字符串处理
- 算法细节系列(9):动态规划之01背包
- 算法细节系列(11):再谈动态规划
- C++ 算法系列之动态规划
- 算法系列1、动态规划
- 【LeetCode系列】动态规划算法
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 【算法】之动态规划
- 算法导论系列文章之动态规划-钢条切割
- topcoder算法教程翻译系列之动态规划
- 算法导论之动态规划 字符串拆分问题
- 一张图,教你用25种可视化工具如何完成
- JavaScript中本地对象、内置对象和宿主对象
- C语言程序设计(7)
- Spring IOC 透彻解析
- Java之JSON数据
- 算法细节系列(14):动态规划之字符串处理
- pvanet训练并检测自己的数据_流程_报错_总结
- C语言程序设计(8)
- Python中的元类(__metaclass__)
- 手机常用分页加载loading框
- IOS开源项目--通讯录(附源代码)
- Java多线程(二)
- Android Studio 中 layout 目录分类
- Ubuntu14.04下配置PHP7.0+Apache2+Mysql5.7