在Java的面试中,最长公共子序列(Longest Common Subsequence,LCS)问题是常见的动态规划问题。它涉及寻找两个序列中最长的共同子序列的长度。本文将介绍一道经典的Java面试题——最长公共子序列,并提供详细的解析和解题思路。
题目
给定两个字符串s1和s2,要求编写一个函数来计算它们的最长公共子序列的长度。
示例
输入:s1 = "ABCD", s2 = "ACDF" 输出:3(最长公共子序列为 "ACD")
解析与解题思路
最长公共子序列(LCS)问题可以通过动态规划来解决。下面是使用动态规划解决该问题的具体步骤:
- 创建一个二维数组dp,其中dp[i][j]表示字符串s1的前i个字符和字符串s2的前j个字符的最长公共子序列的长度。
- 初始化dp数组的第一行和第一列为0,表示当一个字符串为空时,最长公共子序列的长度为0。
- 遍历字符串s1和s2的所有字符,对于每个字符,比较它们是否相等:如果s1[i-1]和s2[j-1]相等,则将dp[i][j]设置为dp[i-1][j-1] + 1,表示在最长公共子序列的基础上加上当前字符。如果s1[i-1]和s2[j-1]不相等,则将dp[i][j]设置为dp[i-1][j]和dp[i][j-1]中的较大值,表示取左边或上边的最长公共子序列长度。
- 最终结果为dp[m][n],其中m和n分别为字符串s1和s2的长度。
下面是使用动态规划解决该问题的Java代码示例:
public class LongestCommonSubsequence {
public static int longestCommonSubsequence(String s1, String s2) {
int m = s1.length();
int n = s2.length();
int[][] dp = new int[m + 1][n + 1];
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;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[m][n];
}
public static void main(String[] args) {
String s1 = "ABCD";
String s2 = "ACDF";
int length = longestCommonSubsequence(s1, s2);
System.out.println("Length of longest common subsequence: " + length);
}
}
在上述代码中,我们使用动态规划的方法计算字符串s1和s2的最长公共子序列的长度。通过比较字符是否相等,并根据动态规划的思想,我们填充二维数组dp,最终得到最长公共子序列的长度。
结论
通过使用动态规划,我们可以高效地计算两个字符串的最长公共子序列的长度。这道经典的Java面试题考察了面试者对动态规划思想和算法的理解。理解动态规划的基本原理和思考问题的方式对于解决复杂的优化问题至关重要。在面试中,清晰地解释算法思路和实现过程,展现出自己的编程能力和问题解决能力,将为面试成功奠定基础。
学java,就到java编程狮!