zoukankan      html  css  js  c++  java
  • 最长公共子序列

    此博客链接:https://www.cnblogs.com/ping2yingshi/p/14191254.html

    最长公共子序列

    题目链接:https://www.nowcoder.com/practice/6d29638c85bb4ffd80c020fe244baf11?tpId=188&&tqId=36860&rp=1&ru=/activity/oj&qru=/ta/job-code-high-week/question-ranking

    题目

    给定两个字符串str1和str2,输出连个字符串的最长公共子序列。如过最长公共子序列为空,则输出-1。
    示例1

    输入

    "1A2C3D4B56","B1D23CA45B6A"

    返回值

    "123456"
    

    说明

    "123456"和“12C4B6”都是最长公共子序列,任意输出一个。

    题解

    这题想了好久无从下手,感觉以前的动态规划思想用不了,参考了一篇博客,但是看得我迷迷糊糊的,哎。

    参考链接:https://blog.csdn.net/hrn1216/article/details/51534607

    思路:

    利用上面博客的三个公式,求出最长子序列的长度,然后通过反转求解结果,但是结果还是不对,没有通过全部示例。

    代码

    import java.util.*;
    public class Solution {
        public String LCS (String s1, String s2) {
            // write code here
            int len1 = s1.length();
            int len2 = s2.length();
            int[][] result = new int[s1.length() + 1][s2.length() + 1];//默认赋值,[0][?],[?][0]默认两侧皆0,类似公式中0的场景
            //构造一个LCS长度数组
            for (int i = 1; i <= len1; i++) {
                for (int j = 1; j <= len2; j++) {
                    if (s1.charAt(i - 1) == s2.charAt(j - 1)) {//对应公式第二条相等
                        result[i][j] = result[i - 1][j - 1] + 1;
                    } else {//对应公式第三条不相等
                        result[i][j] = Math.max(result[i][j - 1], result[i - 1][j]);
                    }
                }
            }
    
            //反推结果
            int i = len1;
            int j = len2;
            StringBuffer sb = new StringBuffer();//作为结果
            while (i > 0 && j > 0) {//这里其实处理了i=0,j=0的,对应公式0的反推场景
                if (s1.charAt(i - 1) == s2.charAt(j - 1)) {//反推公式中不相等的场景
                    //该值一定是被选取到的,根据之前的公式,知道两条字符串的下标都前进一位
                    sb.append(s1.charAt(i - 1));
                    i--;
                    j--;
                } else {//对应公式中不相等的反推场景
                    if (result[i][j - 1] > result[i - 1][j]) {//找大的那个方向,此处是左边大于上面,则该处的结果是来自左边
                        j--;
                    } else if (result[i][j - 1] < result[i - 1][j]) {
                        i--;
                    } else if (result[i][j - 1] == result[i - 1][j]) {
                        //对于有分支的可能时,我们选取单方向
                        j--;   //此结果对于结果1所选取方向,str1的下标左移一位.替换为j--,则结果对应与结果2选取的方向
                    }
                }
            }
            //由于是从后往前加入字符的,需要反转才能得到正确结果
            return sb.reverse().toString();
        }
    }
  • 相关阅读:
    NVCC编译器
    BMP文件格式及读写
    Vim 命令 【转】
    NFS文件系统配置 和 GLIBC更新
    cuda vector addition
    hdu4758 Walk Through Squares 自动机+DP
    hdu4722 Good Numbers
    hdu4725 The Shortest Path in Nya Graph
    Anaconda-科学计算的 Python 发行版
    OUC_NewACMer_Personal_#1 题解
  • 原文地址:https://www.cnblogs.com/ping2yingshi/p/14191254.html
Copyright © 2011-2022 走看看