其他分享
首页 > 其他分享> > Leetcode 1092 最短公共超序列

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