Java 两个字符串的公共子字符串
这个特别的面试问题难住了我:Java 两个字符串的公共子字符串,java,algorithm,Java,Algorithm,这个特别的面试问题难住了我: 给定两个字符串S1和S2。查找最长的子字符串,其前缀为S1,后缀为S2 通过谷歌,我发现了以下解决方案,但我不太明白它在做什么 public String findLongestSubstring(String s1, String s2) { List<Integer> occurs = new ArrayList<>(); for (int i = 0; i < s1.length(); i++) {
给定两个字符串S1和S2。查找最长的子字符串,其前缀为S1,后缀为S2
通过谷歌,我发现了以下解决方案,但我不太明白它在做什么
public String findLongestSubstring(String s1, String s2) {
List<Integer> occurs = new ArrayList<>();
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) == s2.charAt(s2.length()-1)) {
occurs.add(i);
}
}
Collections.reverse(occurs);
for(int index : occurs) {
boolean equals = true;
for(int i = index; i >= 0; i--) {
if (s1.charAt(index-i) != s2.charAt(s2.length() - i - 1)) {
equals = false;
break;
}
}
if(equals) {
return s1.substring(0,index+1);
}
}
return null;
}
公共字符串findLongestSubstring(字符串s1、字符串s2){
List occurs=新建ArrayList();
对于(int i=0;i=0;i--){
如果(s1.charAt(index-i)!=s2.charAt(s2.length()-i-1)){
等于等于假;
打破
}
}
如果(等于){
返回s1.子字符串(0,索引+1);
}
}
返回null;
}
我的问题:
- 你是如何发现这个解决方案的李>
你从哪里找到的解决方案?它是由一个可信的、受人尊敬的程序员写的吗?如果你对此不确定,那么它可能不值得一读。人们可以编写非常复杂和低效的代码来完成非常简单的事情,而不值得理解算法 与试图理解其他人的解决方案相比,自己想出解决方案可能更容易。我认为你通过这种方式更好地理解了这个问题,逻辑就变成了你自己的了。随着时间的推移和实践,思维过程将开始变得更加自然。熟能生巧
无论如何,我在Python中使用了一个更简单的实现(剧透警报!)。我建议您先自己找出解决方案,然后再与我的方案进行比较。您从哪里找到的解决方案?它是由一个可信的、受人尊敬的程序员写的吗?如果你对此不确定,那么它可能不值得一读。人们可以编写非常复杂和低效的代码来完成非常简单的事情,而不值得理解算法 与试图理解其他人的解决方案相比,自己想出解决方案可能更容易。我认为你通过这种方式更好地理解了这个问题,逻辑就变成了你自己的了。随着时间的推移和实践,思维过程将开始变得更加自然。熟能生巧 无论如何,我在Python中使用了一个更简单的实现(剧透警报!)。我建议您先自己找出解决方案,然后与我的方案进行比较。问题的第2部分 以下是一个较短的变体:
public String findLongestPrefixSuffix(String s1, String s2) {
for( int i = Math.min(s1.length(), s2.length()); ; i--) {
if(s2.endsWith(s1.substring(0, i))) {
return s1.substring(0, i);
}
}
}
我正在使用Math.min
查找最短字符串的长度,因为我不需要也无法比较超过该长度的字符串
someString.substring(x,y)
返回从字符x
开始并在字符y
处停止读取某个字符串时得到的字符串。我从可能的最大子字符串(s1
或s2
)返回到可能的最小子字符串,即空字符串。这样,当我的条件第一次为真时,它将是实现它的最大可能子字符串
如果愿意,可以反过来,但必须引入一个变量,以节省满足条件的最长子字符串的长度:
public static String findLongestPrefixSuffix(String s1, String s2) {
if (s1.equals(s2)) { // this part is optional and will
return s1; // speed things up if s1 is equal to s2
} //
int max = 0;
for (int i = 0; i < Math.min(s1.length(), s2.length()); i++) {
if (s2.endsWith(s1.substring(0, i))) {
max = i;
}
}
return s1.substring(0, max);
}
公共静态字符串findLongestPrefixSuffix(字符串s1、字符串s2){
如果(s1.equals(s2)){//这部分是可选的,将
返回s1;//如果s1等于s2,则加快速度
} //
int max=0;
对于(int i=0;i
作为记录:在后一个示例中,您可以从i=1
开始,以获得一点点额外的性能。除此之外,您还可以使用i
指定后缀的长度(至少为您想要的长度)如果写入Math.min(s1.length(),s2.length())-x
,则可以使用x
指定找到的子字符串的最长长度。对于第一种解决方案,这两种情况都是可能的,但最小长度更复杂一些
你问题的第一部分 在
Collections.reverse上面的部分中,代码作者在s1
中搜索s2
最后一个字母所在的所有位置,并保存该位置
下面的内容本质上就是我的算法所做的,不同的是,他不检查每个子字符串,只检查那些以s2
的最后一个字母结尾的子字符串
这是一种加快速度的优化。如果速度不是那么重要,我天真的实现就足够了 你问题的第二部分
以下是一个较短的变体:
public String findLongestPrefixSuffix(String s1, String s2) {
for( int i = Math.min(s1.length(), s2.length()); ; i--) {
if(s2.endsWith(s1.substring(0, i))) {
return s1.substring(0, i);
}
}
}
我正在使用Math.min
查找最短字符串的长度,因为我不需要也无法比较超过该长度的字符串
someString.substring(x,y)
返回从字符x
开始并在字符y
处停止读取某个字符串时得到的字符串。我从可能的最大子字符串(s1
或s2
)返回到可能的最小子字符串,即空字符串。这样,当我的条件第一次为真时,它将是实现它的最大可能子字符串
如果愿意,可以反过来,但必须引入一个变量,以节省满足条件的最长子字符串的长度:
public static String findLongestPrefixSuffix(String s1, String s2) {
if (s1.equals(s2)) { // this part is optional and will
return s1; // speed things up if s1 is equal to s2
} //
int max = 0;
for (int i = 0; i < Math.min(s1.length(), s2.length()); i++) {
if (s2.endsWith(s1.substring(0, i))) {
max = i;
}
}
return s1.substring(0, max);
}
公共静态字符串findLongestPrefixSuffix(字符串s1、字符串s2){
如果(s1.equals(s2)){//这部分是可选的,将
返回s1;