zoukankan      html  css  js  c++  java
  • b_nk_最长公共子序列 & 最长公共子串(dp+双指针 | 记录最长lms的长度,以及结尾位置)

    最长公共子序列

    给出两个字符串A B,求A与B的最长公共子序列字符串

    思路:一开始直接字符串拼接做的,t了

    String f[][];
    String my_max(String a, String b) {
        return (a.length()<b.length() ? b : a);
    }
    for (int i=1; i<=n; i++)
    for (int j=1; j<=m; j++) {
        if (s[i]==t[j]) f[i][j]=f[i-1][j-1]+s[i];
        else f[i][j]=my_max(f[i-1][j], f[i][j-1]);
    }
    

    优化:我没有用好f[i][j]的意义,我只需要求出f[i][j]的最长长度,然后双指针判断就行了,逻辑见注释

    import java.util.*;
    import java.math.*;
    import java.io.*;
    class Solution {
        int N=1005, n,m,f[][];
        String get_lms(char[] s, char[] t) {
            int i=n, j=m;
            StringBuilder ans=new StringBuilder();
            while (i>0 && j>0) {
                if (s[i]==t[j]) {
                    ans.append(s[i]);
                    i--; j--;
                } else { //(s的前i-1个字符和t的前j个的lms」比「s的前i个和t的前j-1个的lms)短,则证明我保留s的第i个字符更优
                    if (f[i-1][j]<f[i][j-1]) j--;
                    else i--;
                }
            }
            return ans.reverse().toString();
        }
        void init() {
            Scanner sc = new Scanner(new BufferedInputStream(System.in));
            String a=sc.next(), b=sc.next();
            f=new int[N][N]; n=a.length(); m=b.length();
            a=' '+a; b=' '+b;
            char s[]=a.toCharArray(), t[]=b.toCharArray();
    
            for (int i=1; i<=n; i++)
            for (int j=1; j<=m; j++) {
                if (s[i]==t[j]) f[i][j]=f[i-1][j-1]+s[i];
                else f[i][j]=Math.max(f[i-1][j], f[i][j-1]);
            }
            System.out.println(get_lms(s,t));
        }
    }
    public class Main{
        public static void main(String[] args) throws IOException {  
            Solution s = new Solution();
            s.init();
        }
    }
    

    最长公共子串

    给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1。

    思路:记录最长长度与达到最长长度时的子串的结尾位置

    const int N=5005;
    class Solution {
    public:
        int f[N][N]; 
        string LCS(string s, string t) {
            int n=s.size(), m=t.size(), maxL=0, e=-1;
            for (int i=1; i<=n; i++)
            for (int j=1; j<=m; j++) {
                if (s[i-1]==t[j-1]) {
                    f[i][j]=f[i-1][j-1]+1;
                } else {
                    f[i][j]=0;
                }
                if (f[i][j]>maxL)
                    maxL=f[i][j], e=i-1;
            }
            if (e==-1) return "-1";
            return s.substr(e-maxL+1, maxL);
        }
    };
    
  • 相关阅读:
    在Android studio中,测试输出数组中最大子数组的和
    我所理解的软件开发模式
    java实现随机输出300题四则运算
    Demo(3月28日)
    关于构建之法中小飞问题的个人看法
    对搭档代码的一些意见
    项目复审
    安卓UI测试(基于android studio环境 espresso框架)
    读构建之法后的一些个人感受
    思考题
  • 原文地址:https://www.cnblogs.com/wdt1/p/13883800.html
Copyright © 2011-2022 走看看