动态规划策略编程实现最长公共子序列问题代码

public class LongestCommonSubsequence {
   static int lcs(String s1, String s2) {
       int m = s1.length();
       int n = s2.length();
       int[][] dp = new int[m + 1][n + 1];
       int[][] path = new int[m + 1][n + 1];

       // 初始化dp数组的第一行和第一列为0
       for (int i = 0; i <= m; i++) {
           dp[i][0] = 0;
       }
       for (int j = 0; j <= n; j++) {
           dp[0][j] = 0;
       }

       // 使用动态规划计算lcs,并记录路径信息到path数组中
       for (int i = 1; i <= m; i++) {
           for (int j = 1; j <= n; j++) {
               if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                   dp[i][j] = dp[i - 1][j - 1] + 1;
                   path[i][j] = 1; // 左上方转移
               } else {
                   if (dp[i - 1][j] >= dp[i][j - 1]) {
                       dp[i][j] = dp[i - 1][j];
                       path[i][j] = 2; // 上方转移
                   } else {
                       dp[i][j] = dp[i][j - 1];
                       path[i][j] = 3; // 左方转移
                   }
               }
           }
       }

       // 回溯得到最长公共子序列
       StringBuilder sb = new StringBuilder();
       int i = m, j = n;
       while (i > 0 && j > 0) {
           if (path[i][j] == 1) {
               sb.append(s1.charAt(i - 1));
               i--;
               j--;
           } else if (path[i][j] == 2) {
               i--;
           } else {
               j--;
           }
       }

       // 将sb中的字符反转得到最长公共子序列
       String lcs = sb.reverse().toString();
       System.out.println("最长公共子序列是: " + lcs);

       // 返回lcs的长度
       return dp[m][n];
   }

   public static void main(String[] args) {
       String s1 = "ABCDGHLQR";
       String s2 = "AEDPHR";
       System.out.println("最长公共子序列长度是: " + lcs(s1, s2));
   }
}

 

版权声明:
作者:斌蔚司李
链接:http://www.gangpaoyl.cn/?p=480
来源:斌蔚司李
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>