题解 | #查找两个字符串a,b中的最长公共子串#

查找两个字符串a,b中的最长公共子串

http://www.nowcoder.com/practice/181a1a71c7574266ad07f9739f791506

使用动态规划进行解决

dp[i][j]表示以str1[i]和str2[j]结尾的公共子串的长度,因此可以得到递推式

dp[i][j] = dp[i-1][j-1] + (1 & str1[i]==str2[j])

import java.util.*;

public class Main{
    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str1 = sc.nextLine();
            String str2 = sc.nextLine();
            String longest =  longestCommonSubstring(str1,str2);
            System.out.println(longest);
        }
    }
    
    public static String longestCommonSubstring(String str1, String str2){
        if(str1.length() == 0 || str2.length() == 0){
            return "";
        }
        // 保证str1的长度<=str2
        if(str1.length() > str2.length()){
            return longestCommonSubstring(str2, str1);
        }
        int m = str1.length(), n = str2.length();
        //使用dp[i][j]表示以i,j结尾的最长公共子串长度
        //dp[i][j] = dp[i-1][j-1] + 1;
        int[][] dp = new int[m][n];
        for(int i = 0; i < m; i++){
            if(str1.charAt(i) == str2.charAt(0)){
                dp[i][0] = 1;
            }
        }
        for(int i = 0; i < n; i++){
            if(str1.charAt(0) == str2.charAt(i)){
                dp[0][i] = 1;
            }
        }
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                if(str1.charAt(i) == str2.charAt(j)){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }
            }
        }
        int maxLen = 0;
        int end = 0; //从str1上取的end,也就是表示优先取str1上第一次出现的
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(dp[i][j] > maxLen){
                    maxLen = dp[i][j];
                    end = i;
                }
            }
        }
        return str1.substring(end-maxLen+1 ,end+1);
        
    }
    
}
全部评论

相关推荐

牛客737698141号:他们可以看到在线简历的。。。估计不合适直接就拒了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务