Javaは、2つの文字列の中で最も長い共通の部分文字列を見つけます

タイトル説明

2つの文字列str1とstr2を指定して、2つの文字列の最長の共通部分文字列を出力します。最長の共通部分文字列が空の場合は、-1を出力します。

例1

入る

"1AB2345CD","12345EF"

戻り値

"2345"

 

import java.util.*;


public class Solution {
    /**
     * longest common substring
     * @param str1 string字符串 the string
     * @param str2 string字符串 the string
     * @return string字符串
     *
     * 滑动窗口
     */
    public String LCS (String str1, String str2) {
        //记录最大公共子串记录
        StringBuilder sb = new StringBuilder();
        int start = 0;
        int end = 1;
        
        //str1.substring(start,end) 是左闭右开的 想要substring str1整体字符串 end就得length+1
        while(end < str1.length()+1){
            //如果str2包含str1截取的部分
            if(str2.contains(str1.substring(start,end))){
                //如果最大公共子串的长度 < 上一步中公共子串str1截取的长度
                //那么sb清空,重新记录公共子串
                if(sb.length() < (end - start)){
                    sb.delete(0,sb.length());
                    //截取[start,end)之间的字符串,追加到sb中
                    sb.append(str1,start,end);
                    //已提交的代码中 没有在此处加end++ 会导致比较长度一次循环 然后再进行第二次循环才会end++滑动窗口
                    end++;
                }else{
                    //当前序的滑动窗口start向后滑动后,会存在sb.length() >= (end - start)的情况
                    //即最长公共子串会碰撞长度相同的情况 此时滑动窗口end位置后移
                    end++;
                }
            }else{
                //向后滑动窗口的起始位置
                //这个算法我曾经疑惑,假如出现start>end,程序不是会crash么
                //通过debug发现,当start==end时,substring获取的是"",此时contains必然为true
                //所以当start == end时,必然会走end++分支
                start++;
            }
        }
        
        //如果最长公共子串记录为0 那么说明没有公共子串
        if(sb.length() == 0){
            return "-1";
        }
        
        return sb.toString();
    }
}

 

おすすめ

転載: blog.csdn.net/luzhensmart/article/details/112772519