初见这道题想的很难,比如动态规划算法。
但是仔细观察以后,发现有点类似于数据库中的Nested Loop的思想,无非是用一张表驱动另一张表,循环找想要的东西而已。
用图来说明,就是将短的字符串从右向左遍历截取,看看截取的结果在不在长串中,如果在就保存下来,如果不在就继续截取。
当左右指针i和k相遇时,开始下一趟,k归位到最右,i++。以此类推。
最后,将保存的结果按长短排序,打印最长的:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String a = in.nextLine();
String b = in.nextLine();
String longStr;
String shortStr;
if (a.length() > b.length()) {
longStr = a;
shortStr = b ;
} else {
longStr = b;
shortStr = a;
}
List<String> list = new ArrayList<>();
for (int i = 0; i < shortStr.length(); i++) {
for (int k = shortStr.length(); i < k ; k--) {
if (longStr.contains(shortStr.substring(i, k))) {
list.add(shortStr.substring(i, k));
}
}
}
list.sort((o1, o2) -> o2.length() - o1.length());
System.out.println(list.get(0));
}
}
}
但是这段代码在执行的时候,我发现list里充斥大量的元素,因此我想我的解法应该很慢,而且空间占用很多。
进一步思考我发现每次匹配的时候,如果引入一个长度变量记录上一次的子串长度,当下一次子串比上一次更长的时候才记录到list里,岂不是很好,于是代码优化了一下:
package huawei;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String a = in.nextLine();
String b = in.nextLine();
String longStr;
String shortStr;
if (a.length() > b.length()) {
longStr = a;
shortStr = b ;
} else {
longStr = b;
shortStr = a;
}
List<String> list = new ArrayList<>();
int maxLength = 0;
for (int i = 0; i < shortStr.length(); i++) {
for (int k = shortStr.length(); i < k ; k--) {
int length = shortStr.substring(i, k).length();
if (longStr.contains(shortStr.substring(i, k)) && maxLength < length) {
list.add(shortStr.substring(i, k));
maxLength = length;
}
}
}
list.sort((o1, o2) -> o2.length() - o1.length());
System.out.println(list.get(0));
}
}
}
从代码的执行情况来看,确实有效果: