最长公共字串(动态规划)

落日映苍穹つ 2022-08-18 02:19 297阅读 0赞

【题目】
给定两个字符串 str1 和 str2,返回两个字符串的最长公共子串。
【举例】
str1 =“1AD12345CD ”, str2 =“12345EF”。返回“12345”。
【要求】
如果str1 长度为M, str2长度为N,实现时间复杂度为O(M*N),额外空间复杂度

为O(1)的方法。

代码实现:

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <cstdio>
  5. #include <cmath>
  6. #include <cstdlib>
  7. #include <cstring>
  8. using namespace std;
  9. /* 经典的动态规划,利用dp[i][j]空间复杂度为O(M*N),还可以进行优化
  10. 因为dp[i][j]只和dp[i-1][j-1]有关,所以可以按照斜线方向来计算,s
  11. 只需要一个变量就可以计算出所有位置的值
  12. */
  13. char* getSubList(const char* str1, const char* str2)
  14. {
  15. if (str1 == NULL || str2 == NULL)
  16. {
  17. return NULL;
  18. }
  19. int rows = 0; //斜线开始位置的行
  20. int cols = strlen(str2) - 1; //斜线开始位置的列
  21. int maxlen = 0; //记录最大长度
  22. int ends = 0; //最大长度更新的时候,记录字串结束的位置
  23. int i = 0, j = 0, len = 0;
  24. char* pres = NULL;
  25. while(rows < strlen(str1))
  26. {
  27. /* 开始进行斜线往下求值 */
  28. i = rows;
  29. j = cols;
  30. len = 0;
  31. /* 边界条件 */
  32. while(i < strlen(str1) && j < strlen(str2))
  33. {
  34. if (str1[i] != str2[j])
  35. {
  36. len = 0;
  37. }
  38. else
  39. {
  40. len++;
  41. }
  42. /* 记录最大值 */
  43. if (len > maxlen)
  44. {
  45. ends = i;
  46. maxlen = len;
  47. }
  48. i++;
  49. j++;
  50. }
  51. if(cols > 0) //斜线开始位置列先向左移动
  52. {
  53. cols--;
  54. }
  55. else//列移动到最左之后,行往下移动
  56. {
  57. rows++;
  58. }
  59. }
  60. pres = new char[maxlen+1];
  61. memcpy(pres,str1+ends-maxlen+1,maxlen);
  62. pres[maxlen] = '\0';
  63. return pres;
  64. }
  65. int main()
  66. {
  67. char str1[] = "1AD12345CD";
  68. char str2[] = "12345EF";
  69. cout << getSubList(str1,str2) << endl;
  70. }

发表评论

表情:
评论列表 (有 0 条评论,297人围观)

还没有评论,来说两句吧...

相关阅读

    相关 动态规划 公共

    核心思路和最长公共子序列一样 区别在于子串必须连续 可以先看我之前这篇文章 [最长公共子序列问题总结][Link 1] 最长公共子串同样是构造二维数组存储最大值,只不过去