给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。
注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。 数据范围:字符串长度:
进阶:时间复杂度:,空间复杂度:
import java.util.Scanner; import java.io.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args)throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str1 = br.readLine(); String str2 = br.readLine(); if(str1.length()>str2.length()){ String str =str1; str1 = str2; str1 = str; } if(str2.contains(str1)){ System.out.println(str1.length()); return; } for(int i = 1;i<str1.length();i++){ for(int j = 0;j<=i;j++){ String str; str = str1.substring(j,str1.length()-(i-j)); if(str2.contains(str)){ System.out.println(str.length()); return; } } } System.out.println(0); } }19ms,求大佬分析为啥比榜上的慢这么多
import java.util.Scanner; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Collection; import java.util.Collections; import java.util.HashMap; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line1 = br.readLine(); String line2 = br.readLine(); // 找出短的字符串 String shortStr = line1.length() <= line2.length() ? line1 : line2; String longStr = line1.length() <= line2.length() ? line2 : line1; HashMap<String, Integer> map = new HashMap<>(); for (int i = 0; i < shortStr.length(); i++) { for (int j = i + 1; j <= shortStr.length(); j++) { String sub = shortStr.substring(i, j); if (longStr.contains(sub)) { map.put(sub, sub.length()); } } } // 计算最大长度 if (map.size() > 0) { Collection<Integer> values = map.values(); int max = Collections.max(values); System.out.println(max); } else { System.out.println(0); } } }
import java.io.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) throws IOException{ BufferedReader br =new BufferedReader(new InputStreamReader(System.in)); String str1=br.readLine(); String str2=br.readLine(); int len1=str1.length(); int len2=str2.length(); //记录str1的第i字符和str2的第j字符的最长公共子串长度 int[][] dp = new int[len1+1][len2+1]; //maxLCS记录最终的最长公共子串长度 int maxLCS=0; for(int i=1;i<=len1;i++){ for(int j=1;j<=len2;j++){ //str1.charAt(i-1)==str2.charAt(j-1)时,最长公共子串长度dp[i][j]等于没有str1的第i //字符和str2的第j字符参与比较时的最长公共子串长度+1 if(str1.charAt(i-1)==str2.charAt(j-1)) dp[i][j]=dp[i-1][j-1]+1; if(dp[i][j]>maxLCS) maxLCS=dp[i][j]; } } System.out.println(maxLCS); } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String str1=in.nextLine(); String str2=in.nextLine(); int maxLength=0; //表示str1的i位置和str2的j位置时候,最长公共子串的长度为dp[i+1][j+1]; int dp[][]=new int[str1.length()+1][str2.length()+1]; for(int i=0;i<str1.length();i++){ for(int j=0;j<str2.length();j++){ //如果字符相等的时候 if(str1.charAt(i)==str2.charAt(j)){ //维护dp数组,使其最长长度为i-1,j-1的位置长度+1 dp[i+1][j+1]=dp[i][j]+1; //维护最大长度 if(dp[i+1][j+1]>maxLength){ maxLength=dp[i+1][j+1]; } //不等说明当前位置最大长度为0 }else{ dp[i+1][j+1]=0; } } } System.out.print(maxLength); } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNextLine()) { // 注意 while 处理多个 case String str1 = in.nextLine(); String str2 = in.nextLine(); if(str1.length()>str2.length()){ String temp = str1; str1 =str2; str2 = temp; } String[] str1Arr = str1.split(""); String[] str2Arr = str2.split(""); int maxLen = 0; for(int i = 0;i < str1Arr.length; i++){ int temp = 0; for(int j = 0,k = i;j<str2Arr.length&&k<str1Arr.length;j++){ String m = str1Arr[k]; String n = str2Arr[j]; if(m.equals(n)){ temp++; k++; }else{ if(temp>maxLen) maxLen=temp; temp=0; k=i; } } if(temp>maxLen) maxLen=temp; } System.out.println(maxLen); } } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String str1 = in.next(); String str2 = in.next(); char[] schar1 = str1.toCharArray(); char[] schar2 = str2.toCharArray(); int max = 0; int[][] dp = new int[schar1.length][schar2.length]; for (int i = 0; i < schar1.length; i++) { for (int j = 0; j < schar2.length; j++) { if (schar1[i] == schar2[j]) { if (i == 0 || j == 0) { dp[i][j] = 1; } else { dp[i][j] = dp[i - 1][j - 1] + 1; } } max = Math.max(max, dp[i][j]); } } System.out.println(max); } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNext()) { // 注意 while 处理多个 case String a = in.nextLine(); String b = in.nextLine(); int len1 = a.length(); int len2 = b.length(); int max = 0; int samelen=0; String tmp; for (int i = 0; i < len1; i++) for (int j = i + 1; j <=len1; j++) { tmp = a.substring(i, j); samelen = len2 - b.replaceFirst(tmp, "").length(); max = samelen > max ? samelen : max; // System.out.println(tmp+","+max+","+b.replace(tmp, "")); } System.out.println(max); } } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 获取输入的字符串 String str1 = in.nextLine(); String str2 = in.nextLine(); // 将字符串转换为字符数组 char[] char1 = str1.toCharArray(); char[] char2 = str2.toCharArray(); // 定义一个二维数组,用来存贮第i,j位置的最大公共字串的长度 int[][] dp = new int[str1.length()+1][str2.length()+1]; // 定义一个变量,用来得到最大功能字串的长度 int maxLength = 0; // 通过循环查找最大功能字串 for (int i = 1; i <= char1.length; i++) { for (int j = 1; j <= char2.length; j++) { if (char1[i-1] == char2[j-1]) { // i,j位置的最大公共字串即为i-1,j-1位置的最大公共字串加上本身就OK dp[i][j] = dp[i - 1][j - 1] + 1; } else { // 不等,ij位置最大公共字串即为0; dp[i][j] = 0; } maxLength = Math.max(maxLength, dp[i][j]); } } // 输出结果 System.out.println(maxLength); } }
一段时间不写 有点懵逼了
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { private Integer[][] memo; private int res = 0; public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNextLine()) { // 注意 while 处理多个 case String a = in.nextLine(); String b = in.nextLine(); Main m = new Main(); System.out.println(m.lcs(a, b)); } } public int lcs(String a, String b) { int m = a.length(); int n = b.length(); int max = 0; // dp[i][j] : a[i-1]结尾和b[j-1]结尾 的最长公共连续子串 int[][] dp = new int[m + 1][n + 1]; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (a.charAt(i - 1) == b.charAt(j - 1)) { dp[i][j] = dp[i - 1][j - 1] + 1; max = Math.max(max, dp[i][j]); }else { dp[i][j] = 0; } } } return max; } }
使用滚动数组,将常规的二维数组dp优化成一维数组
public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; while(Objects.nonNull(str = br.readLine())) { String s1 = str, s2 = br.readLine(); int ans = longest(s1,s2); System.out.println(ans); } } private static int longest(String s1, String s2) { int len1 = s1.length(), len2 = s2.length(), max = 0; int dp[] = new int[len2 + 1]; for (int i = 1; i <= len1; ++i) { int lt = dp[0]; // 可看作二维数组中,dp[i - 1][j - 1]; dp[0] = 0; for (int j = 1; j <= len2; ++j) { int temp = dp[j]; // 在更新前,表示的为dp[i - 1][j]; dp[j] = s1.charAt(i - 1) == s2.charAt(j - 1) ? lt + 1 : 0; lt = temp; max = Math.max(dp[j], max); } } return max; }
import java.io.BufferedReader; import java.io.IOException; import java.util.*; public class Main { public static void maxLength (String minStr,String maxStr){ int len = minStr.length(); ArrayList <String> arr =new <String> ArrayList(); int maxLen =0; for(int i=0;i<len;i++){ for(int j=i+1;j<=len;j++){ // arr.add(); String stt = minStr.substring(i,j); if(maxStr.contains(stt)){ if(maxLen<stt.length()) maxLen = stt.length(); } } } System.out.print(maxLen); } public static void main(String[] args) throws IOException { Scanner scan = new Scanner(System.in); String str1 = scan.next(); String str2 = scan.next(); int k =0; if(str1.length()>str2.length()){ maxLength(str2,str1); }else{ maxLength(str1,str2); } } }