当前位置:   article > 正文

最长公共子序列(LCS)的python、C、C++、Java实现 LeetCode72、LeetCode1143_python lcs

python lcs

     

目录

一、原理分析

二、代码实现

        1、Python 实现

        2、C语言实现

        3、C++实现

       4、JAVA实现

三、例题解析

        1、LeetCode1143.最长公共子序列

        2、LeetCode72.编辑距离


       最长公共子序列(Longest Common Subsequence,LCS)是一种常见的计算机科学问题,涉及到在两个序列(通常是字符串)中找到最长的子序列,这个子序列是这两个序列共有的。本文将深入探讨LCS的原理、不同编程语言的实现方法,并通过解析Leetcode中的例题来展示其实际应用。

一、原理分析

        最长公共子序列问题可以通过动态规划来解决。

        动态规划是一种将复杂问题分解为更小的子问题,并将这些子问题的解决方案存储在表格中以便重复使用的技术。

        在LCS问题中,我们可以创建一个二维表格,其中每个单元格代表两个输入字符串的一个子字符串,并存储这两个子字符串的最长公共子序列的长度。

为了填充这个表格,我们可以使用以下规则:

  1. 如果两个子字符串的最后一个字符相同,那么他们的LCS长度就是去掉这两个字符后的子字符串的LCS长度加1。
  2. 如果两个子字符串的最后一个字符不同,那么他们的LCS长度就是去掉一个字符串的最后一个字符后的子字符串的LCS长度和去掉另一个字符串的最后一个字符后的子字符串的LCS长度中的最大值。

       通过从输入字符串的末尾开始应用这些规则,并递归地解决更小的子问题,我们可以填充整个表格,并最终找到最长公共子序列的长度。

二、代码实现

        1、Python 实现

  1. def lcs(X, Y):
  2. m = len(X)
  3. n = len(Y)
  4. L = [[0 for j in range(n+1)] for i in range(m+1)]
  5. for i in range(m+1):
  6. for j in range(n+1):
  7. if i == 0 or j == 0:
  8. L[i][j] = 0
  9. elif X[i-1] == Y[j-1]:
  10. L[i][j] = L[i-1][j-1] + 1
  11. else:
  12. L[i][j] = max(L[i-1][j], L[i][j-1])
  13. return L[m][n]

        2、C语言实现

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int max(int a, int b) { return (a > b)? a : b; }
  4. int lcs(char *X, char *Y, int m, int n) {
  5. int L[m+1][n+1];
  6. int i, j;
  7. for (i = 0; i <= m; i++) {
  8. for (j = 0; j <= n; j++) {
  9. if (i == 0 || j == 0) {
  10. L[i][j] = 0;
  11. } else if (X[i-1] == Y[j-1]) {
  12. L[i][j] = L[i-1][j-1] + 1;
  13. } else {
  14. L[i][j] = max(L[i-1][j], L[i][j-1]);
  15. }
  16. }
  17. }
  18. return L[m][n];
  19. }

        3、C++实现

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5. int lcs(string X, string Y) {
  6. int m = X.size();
  7. int n = Y.size();
  8. vector<vector<int>> L(m+1, vector<int>(n+1, 0));
  9. for (int i = 1; i <= m; i++) {
  10. for (int j = 1; j <= n; j++) {
  11. if (X[i-1] == Y[j-1]) {
  12. L[i][j] = L[i-1][j-1] + 1;
  13. } else {
  14. L[i][j] = max(L[i-1][j], L[i][j-1]);
  15. }
  16. }
  17. }
  18. return L[m][n];
  19. }

       4、JAVA实现

  1. public class LCS {
  2. public static int lcs(String X, String Y) {
  3. int m = X.length();
  4. int n = Y.length();
  5. int[][] L = new int[m+1][n+1];
  6. for (int i = 0; i <= m; i++) {
  7. for (int j = 0; j <= n; j++) {
  8. if (i == 0 || j == 0) {
  9. L[i][j] = 0;
  10. } else if (X.charAt(i-1) == Y.charAt(j-1)) {
  11. L[i][j] = L[i-1][j-1] + 1;
  12. } else {
  13. L[i][j] = Math.max(L[i-1][j], L[i][j-1]);
  14. }
  15. }
  16. }
  17. return L[m][n];
  18. }
  19. }

三、例题解析

        1、LeetCode1143.最长公共子序列

            (1)题目链接:https://leetcode.com/problems/longest-common-subsequence/

            (2)题意解析:给定两个字符串text1和text2,找出它们的最长公共子序列的长度。一个字符串的最长公共子序列是指这个字符串与另一个字符串的最长公共子序列。

            (3)解题思路:给定两个字符串text1和text2,找出它们的最长公共子序列的长度。一个字符串的最长公共子序列是指这个字符串与另一个字符串的最长公共子序列。

            (4)AC代码:

  1. class Solution:
  2. def longestCommonSubsequence(self, text1: str, text2: str) -> int:
  3. X = text1
  4. Y = text2
  5. m = len(X)
  6. n = len(Y)
  7. L = [[0 for j in range(n+1)] for i in range(m+1)]
  8. for i in range(m+1):
  9. for j in range(n+1):
  10. if i == 0 or j == 0:
  11. L[i][j] = 0
  12. elif X[i-1] == Y[j-1]:
  13. L[i][j] = L[i-1][j-1] + 1
  14. else:
  15. L[i][j] = max(L[i-1][j], L[i][j-1])
  16. return L[m][n]

        2、LeetCode72.编辑距离

          (1)题目链接:https://leetcode.cn/problems/edit-distance

          (2)题意解析:给定两个单词word1和word2,计算将word1转换为word2所需的最小编辑距离。编辑距离是指将一个单词转换为另一个单词所需的最少单字符编辑(插入、删除或替换)次数。

          (3)解题思路:使用二维数组dp,其中dp[i][j]表示将word1的前i个字符转换为word2的前j个字符所需的最小编辑距离。如果word1[i-1]等于word2[j-1],则dp[i][j]等于dp[i-1][j-1];否则,dp[i][j]等于dp[i-1][j]、dp[i][j-1]和dp[i-1][j-1]中的最小值加1。

          (4)AC代码:

  1. class Solution:
  2. def minDistance(self, word1: str, word2: str) -> int:
  3. X = word1
  4. Y = word2
  5. m = len(X)
  6. n = len(Y)
  7. L = [[0 for j in range(n+1)] for i in range(m+1)]
  8. for i in range(m+1):
  9. for j in range(n+1):
  10. if i == 0 and j == 0:
  11. L[i][j] = 0
  12. elif i == 0 and j != 0:
  13. L[i][j] = j
  14. elif i != 0 and j == 0:
  15. L[i][j] = i
  16. elif X[i-1] == Y[j-1]:
  17. L[i][j] = L[i-1][j-1]
  18. else:
  19. L[i][j] = min(L[i-1][j], L[i][j-1], L[i - 1][j - 1]) + 1
  20. return L[m][n]
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/87396
推荐阅读
相关标签
  

闽ICP备14008679号