Leetcode 1092 最短公共超序列
作者:互联网
C:
#include <stdlib.h> #include <stdio.h> #include <string.h> char *combine(char *base, char *str1, char *str2) { int len = strlen(base), len1 = strlen(str1), len2 = strlen(str2); int point1 = 0, point2 = 0, point = 0; char *re = (char *)malloc(sizeof(char) * (len + len1 + len2)); memset(re, '\0', sizeof(char) * (len + len1 + len2)); for (int i = 0; i < len; i++) { while (point1 < len1 && str1[point1] != base[i]) re[point++] = str1[point1++]; while (point2 < len2 && str2[point2] != base[i]) re[point++] = str2[point2++]; re[point++] = base[i]; point1++; point2++; } while (point1 < len1) re[point++] = str1[point1++]; while (point2 < len2) re[point++] = str2[point2++]; return re; } char *lcs(char *str1, char *str2) { int len1 = strlen(str1), len2 = strlen(str2); int *dp = (int *)malloc(sizeof(int) * (len1 + 1) * (len2 + 1)); char *lcsStr = (char *)malloc(sizeof(char) * (len1 + len2)); memset(dp, 0, sizeof(int) * (len1 + 1) * (len2 + 1)); memset(lcsStr, '\0', sizeof(char) * (len1 + len2)); for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { int key = i * (len2 + 1) + j, leftKey = (i - 1) * (len2 + 1) + j, rightKey = i * (len2 + 1) + j - 1; if (str1[i - 1] == str2[j - 1]) dp[key] = dp[(i - 1) * (len2 + 1) + j - 1] + 1; else { int left = dp[leftKey], right = dp[rightKey]; if (left > right) dp[key] = left; else dp[key] = right; } } } // 恢复 lcs int point1 = len1, point2 = len2, point = 0, len = 0; while (point1 > 0 && point2 > 0) { if (str1[point1 - 1] == str2[point2 - 1]) { lcsStr[point++] = str1[point1 - 1]; point1--; point2--; len++; } else { if (dp[(point1 - 1) * (len2 + 1) + point2] > dp[point1 * (len2 + 1) + point2 - 1]) point1--; else point2--; } } char *re = (char *)malloc(sizeof(char) * (len + 1)); memset(re, '\0', sizeof(char) * (len + 1)); for (int i = len - 1; i >= 0; i--) re[len - 1 - i] = lcsStr[i]; free(dp); free(lcsStr); return re; } char *shortestCommonSupersequence(char *str1, char *str2) { char *base = lcs(str1, str2); char *re = combine(base, str1, str2); free(base); return re; }
JAVA:
public String shortestCommonSupersequence(String str1, String str2) { int len1 = str1.length(), len2 = str2.length(); String base = this.getLongest(str1, str2); return combine(base, str1, str2); } private String combine(String base, String str1, String str2) { int point1 = 0, point2 = 0, len = base.length(), len1 = str1.length(), len2 = str2.length(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < base.length(); i++) { char c = base.charAt(i); if (point1 < len1) { char c1 = str1.charAt(point1); while (c1 != c && point1 < len1 - 1) { sb.append(c1); c1 = str1.charAt(++point1); } } if (point2 < len2) { char c2 = str2.charAt(point2); while (c2 != c && point2 < len2 - 1) { sb.append(c2); c2 = str2.charAt(++point2); } } sb.append(c); point1++; point2++; } if (point1 < len1) sb.append(str1.substring(point1)); if (point2 < len2) sb.append(str2.substring(point2)); return sb.toString(); } //恢复最长同序子序列 private String getLongest(String str1, String str2) { int len1 = str1.length(), len2 = str2.length(); int[][] dp = new int[len1 + 1][len2 + 1]; for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (str1.charAt(i - 1) == str2.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]); } } //恢复最长同序子序列 StringBuilder sb = new StringBuilder(); int point1 = len1, point2 = len2; while (point1 > 0 && point2 > 0) { if (str1.charAt(point1 - 1) == str2.charAt(point2 - 1)) { sb.append(str1.charAt(point1 - 1)); point1--; point2--; } else { if (dp[point1 - 1][point2] > dp[point1][point2 - 1]) point1--; else point2--; } } return sb.reverse().toString(); }
JS:
/** * @param {string} str1 * @param {string} str2 * @return {string} */ var shortestCommonSupersequence = function (str1, str2) { let base = lcs(str1, str2); let re = combine(base, str1, str2); return re; }; var combine = function (base, str1, str2) { let len1 = str1.length, len2 = str2.length, point1 = 0, point2 = 0; let re = ""; for (let i = 0; i < base.length; i++) { let c1, c2, c = base.charAt(i); while (point1 < len1 && (c1 = str1.charAt(point1)) != c) { re += c1; point1++; } while (point2 < len2 && (c2 = str2.charAt(point2)) != c) { re += c2; point2++; } re += c; point1++; point2++; } if (point1 < len1) re += str1.substring(point1); if (point2 < len2) re += str2.substring(point2); return re; } var lcs = function (str1, str2) { let len1 = str1.length, len2 = str2.length; let dp = new Array(len1 + 1); for (let i = 0; i < len1 + 1; i++) { dp[i] = new Array(len2 + 1); dp[i].fill(0) } for (let i = 1; i <= len1; i++) { for (let j = 1; j <= len2; j++) { if (str1.charAt(i - 1) == str2.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = dp[i - 1][j] > dp[i][j - 1] ? dp[i - 1][j] : dp[i][j - 1]; } } let lcsStr = "", point1 = len1, point2 = len2; while (point1 > 0 && point2 > 0) { if (str1.charAt(point1 - 1) == str2.charAt(point2 - 1)) { lcsStr = str1.charAt(point1 - 1) + lcsStr; point1--; point2--; } else { if (dp[point1 - 1][point2] > dp[point1][point2 - 1]) point1--; else point2--; } } return lcsStr; }
标签:1092,len2,str2,str1,最短,char,point1,point2,Leetcode 来源: https://www.cnblogs.com/niuyourou/p/16248981.html