【左程云|程序员代码面试指南】 最长公共子序列(动态规划Java版)

【题目详情】

给定两个字符串str1和str2,输出连个字符串的最长公共子序列。如过最长公共子序列为空,则输出-1。具体见牛客官网,首页 > 在线编程 > 程序员代码面试指南查看提交。链接直达

【输入描述】

输出包括两行,第一行代表字符串str1,第二行代表str2。
(1≤length(str1),length(str2)≤5000)

【输出描述】

输出一行,代表他们最长公共子序列。如果公共子序列的长度为空,则输出-1。

【复杂度】

  • 时间复杂度O(n*m)O(n∗m)
  • 空间复杂度O(n*m)O(n∗m)。(n,m分别表示两个字符串长度)

【完整代码】

import java.util.Scanner;

public class Main{
     
    public static void main(String[] args) {
     
        Scanner sc = new Scanner(System.in);
        String str1 = sc.next();
        String str2 = sc.next();
        System.out.println(lcse(str1, str2));
    }
    public static int[][] getdp(String str1, String str2)
    {
     
        int[][] dp = new int[str1.length()][str2.length()];
        char[] str1Arr = str1.toCharArray();
        char[] str2Arr = str2.toCharArray();
        dp[0][0] = str1Arr[0] == str2Arr[0] ? 1 : 0 ;
        for(int i = 1; i < str1.length(); i++)
        {
     
            //第零列
            dp[i][0] = Math.max(dp[i-1][0], (str1Arr[i] == str2Arr[0] ? 1 : 0));
        }
        for(int j = 1; j < str2.length(); j++)
        {
     
            //第零行
            dp[0][j] = Math.max(dp[0][j-1], (str1Arr[0] == str2Arr[j] ? 1 : 0));
        }
        for(int i = 1; i < str1.length(); i++)
        {
     
            for(int j = 1; j < str2.length(); j++)
            {
     
                //先比较左和上,取大者
                dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]);
                if(str1Arr[i] == str2Arr[j])
                {
     
                    dp[i][j] = Math.max(dp[i-1][j-1]+1, dp[i][j]);
                }
            }
        }
        return dp;
    }
    public static String lcse(String str1, String str2)
    {
     
        int m = str1.length()-1;
        int n = str2.length()-1;
        int[][] dp = new int[m+1][n+1];
        dp = getdp(str1, str2);
        char[] res = new char[dp[m][n]];
        char[] str1Arr = str1.toCharArray();
        char[] str2Arr = str2.toCharArray();
        if(str1 == null || str2 == null || str1.equals("") || str2.equals("") || dp[m][n] == 0)
        {
     
            return "-1";
        }
        int index = res.length - 1;
        //比如res数组长度为7,实际计算过程并不是7次,而是大于等于7次
        while(index >= 0)
        {
     
            if(n > 0 && dp[m][n] == dp[m][n-1])//来自左
            {
     
                n--;
            }
            else if(m > 0 && dp[m][n] == dp[m-1][n])//来自上
            {
     
                m--;
            }
            else
            {
     
                //dp[m][n] == dp[m-1][n-1] + 1 || dp[0][n] == dp[0][n-1] + 1 || dp[m][0] == dp[m-1][0] + 1
                res[index--] = str1Arr[m];
                m--;
                n--;
            }
        }
        return String.valueOf(res);
    }
}

你可能感兴趣的:(互联网笔试刷题,左程云,动态规划,java,算法,动态规划,字符串)