给出两个字符串:
str1 = "abcdefacbccbagfacbacer"
str2 = "abc"
我要找到str1
中由str2
字符子集组成的最长子字符串,在这种情况下它将是 - 7 (acbccba)
。什么是解决这个问题的方法,至少复杂。首先我想到了DP。但是,我认为DP确实不是必需的,因为我们必须搜索子字符串,而不是子序列。然后我虽然后缀树。但这需要额外的预处理时间。
最好的方法是什么?实际上,这个问题是否适用于后缀树或DP?
答案 0 :(得分:5)
迄今为止最简单的方法:
运行时间:O(n+m)
其中n
是str1
的长度,m
是str2
的长度。
(未经测试)代码:
Set<Character> set = new HashSet<>();
for (int i = 0; i < str2.length(); i++) {
set.add(str2.charAt(i));
}
int longest = 0;
int current = 0;
int longestEnd = -1;
for (int i = 0; i < str1.length(); i++) {
if (set.contains(str1.charAt(i)) {
current++;
if (current > longest) {
longest = current;
longestEnd = i + 1;
}
} else {
current = 0;
}
}
String result = "";
if (longest > 0) {
result = str1.substr(longestEnd - longest, longestEnd);
}
答案 1 :(得分:0)
实际上我只能想到一种方式:
答案 2 :(得分:0)
只是一个想法:在[]中包装第二个字符串并使用Pattern的匹配方法:
Pattern p = Pattern.compile("(["+str2+"])");
Matcher m = p.matcher(str1);
m.find();
然后m.group(1)会找到它。
答案 3 :(得分:0)
Perl中经过测试的代码。
use strict;
use warnings;
my $str1 = "abcdefacbccbagfacbacer";
my $str2 = "abc";
my @str1 = split ("", $str1);
my @str2 = split ("", $str2);
my @res = ();
my $index = undef;
my $max = 0;
my @max_char = ();
for(my $i = 0; $i < @str1; $i++){
if ($str1[$i] =~ /[@str2]/){
push (@res , $str1[$i]);
next;
}else{
if(@res > $max){
$max = @res;
@max_char = @res;
$index = $i;
}
@res = ();
}
}
if(@res > $max){
@max_char = @res;
$index = $i;
}
$index = $index - $#max_char - 1;
print "Longest substring = @max_char. Starting from index $index";