最长公共子序列-算法

题目

给定两个字符串,计算出两个字符串中最长的公共子序列,要求顺序需要一致。

解题

使用动态规划从头到尾将结果累加到两个字符串最后的位置

private static int maxCommonSequance(String source1, String source2) {
  int[][] result = new int[source1.length() + 1][source2.length() + 1];
  for (int i = 1; i <= source1.length(); i++) {
    for (int j = 1; j <= source2.length(); j++) {
      if (source1.charAt(i - 1) == source2.charAt(j - 1)) {
        //将前一个结果记在后面的位置上,可以减少对0位置的判断
        result[i][j] = result[i - 1][j - 1] + 1;
      } else {
        //若当前位置不相同,则需要再i-1,j和i,j-1取最短  
        result[i][j] = Math.max(result[i - 1][j], result[i][j - 1]);
      }
    }
  }
  return result[source1.length()][source2.length()];
}

空间优化:

其实只取决于短的那个字符串在i位置的计数即可。这里需要考虑一个问题,因遍历顺序的问题,在短字符串i处原本短的被更新为长的结果,会导致最后的结果失真。解决办法就是先遍历短再遍历长的,即

for(int i=1;i<=longer;i++){
    for(int j=1;j<=shorter;j++){
            .....
    }
}

优化后

private static int maxCommonSequance2(String longer, String shorter) {
  int m = longer.length();
  int n = shorter.length();
  int[] result = new int[n + 1];
  for (int i = 1; i <= m; i++) {
    int[] tmpResult = new int[n + 1];
    for (int j = 1; j <= n; j++) {
      if (longer.charAt(i - 1) == shorter.charAt(j - 1)) {
        tmpResult[j] = result[j - 1] + 1;
      } else {
        tmpResult[j] = Math.max(result[j], tmpResult[j - 1]);
      }
    }
    result = tmpResult;
  }
  return result[n];
}

 

你可能感兴趣的:(算法,算法)