最长公共前后缀查询问题
我们给出一个字符串的集合,在这个集合中有个字符串,编号为的字符串的长度为。我们给出个查询,每个查询是一个整数对,表示我们假定号串在左边,号串在右边,我们要查询的是最大的长度使号串的前缀与号串的后缀相等。
如我们有串:”ACGT”、”AACCGGTT”、“AAAA”,则查询(2,3)的结果为0,因为”AAAA”在右面欲与左面的”AACCGGTT”进行拼接,显然并没有公共的前后缀区域可以使两串拼接。而查询(3,2)的结果为2,因为此时“AAAA”放在了左面欲与右面的”AACCGGTT”拼接,这时有最长的公共区域”AA”。
题目链接:https://www.nowcoder.com/acm/contest/94/E
暴力,暴力,然后存了一下重复数据极限水过的,这题测试数据里应该有不少重复数据。
public class Main {
public static void main(String[] args) {
PrintWriter out = new PrintWriter(System.out);
InputReader reader = new InputReader();
int n = reader.nextInt();
String[] seq = new String[n + 1];
for (int i = 1; i <= n; i++) {
seq[i] = reader.next();
}
int q = reader.nextInt();
HashMap<String, Integer> map = new HashMap<>();
while (q-- > 0) {
int a = reader.nextInt();
int b = reader.nextInt();
String s = "";//用字符串来存查询key
s += a;
s += " ";//加个空格,不然wa,猜测是哈希冲突
s += b;
if (map.containsKey(s)) {
out.println(map.get(s));
continue;
}
int pre = KMP(seq[a].length(), seq[b].length(), seq[a], seq[b]);
map.put(s, pre);
out.println(pre);
}
out.close();
}
//虽然写着kmp但其实是暴力....一时没反应过来kmp怎么写就先暴力了,居然就a了
public static int KMP(int n, int m, String s, String p) {
int i = n - m;
if (i < 0) {
i = 0;
}
while (i < n) {
if (s.substring(i, n).equals(p.substring(0, n - i))) {
return n - i;
}
i++;
}
return 0;
}
}
class InputReader {
//输入挂,略
}
什么?能不能不这么暴力?
附上一个很妙的代码。
public class Main {
static int[] next = new int[300005];
public static void main(String[] args) {
// Scanner reader = new Scanner(System.in);
PrintWriter out = new PrintWriter(System.out);
InputReader reader = new InputReader();
int n = reader.nextInt();
String[] seq = new String[n + 1];
for (int i = 1; i <= n; i++) {
seq[i] = reader.next();
}
int q = reader.nextInt();
StringBuilder check = new StringBuilder();
while (q-- > 0) {
int a = reader.nextInt();
int b = reader.nextInt();
check.append(seq[b] + "*" + seq[a]);
int len = check.length();
setPrefix(len, check.toString());
out.println(next[len]);
check.delete(0, len);
}
out.close();
}
public static void setPrefix(int m, String p) {
int j = 0, k = -1;
next[0] = -1;
while (j < m) {
if (k == -1 || p.charAt(j) == p.charAt(k)) {
j++;
k++;
next[j] = k;
} else
k = next[k];
}
}
}
class InputReader {
//还是输入挂,略
}
打星号太骚了!!!!抄袭大佬的。
运行时间爆减,之前那个真的是极限水过的。