题目
给定一个长度为 n 的字符串,再给定 m 个询问,每个询问包含四个整数 l1,r1,l2,r2,请你判断 [l1,r1] 和 [l2,r2] 这两个区间所包含的字符串子串是否完全相同
字符串中只包含大小写英文字母和数字
输入
8 3
aabbaabb
1 3 5 7
1 3 6 8
1 2 1 2
输出
Yes
No
Yes
public class 哈希表_字符串哈希 {
//初始化,P代表的是进制数,str储存的是a=1,b=2,c=3这样的,h存储的是字符串的前缀哈希值,p存储的是P进制值换算为十进制的值
public static int N = 100010, P = 131;
public static long[] h = new long[N], p = new long[N];
public static void main(String[] args) throws IOException {
//初始化,n是字符串长度,m是操作次数,s是字符串
Scanner in = new Scanner(System.in);
int n = in.nextInt(), m = in.nextInt();
String s = in.next();
p[0] = 1;
//切记切记,这里看好p的大小写
//str[i] - 'a' + 1相当于拿到a-a=0,0+1=1,相当于a=1,b=2,c=3
for (int i = 1; i<=n; i++) {
p[i] = p[i-1] * P;
h[i] = h[i-1] * P + (s.charAt(i-1)-'a'+1);
}
//操作部分
while (m-- > 0) {
int l1 = in.nextInt(), r1 = in.nextInt();
int l2 = in.nextInt(), r2 = in.nextInt();
//判断字串和字串的前缀哈希值是否相同
if (get(l1, r1) == get(l2, r2)) {System.out.println("Yes");}
else {System.out.println("No");}
}
}
//利用前缀和找到区间和,再进行右移操作,就能得到字串的前缀哈希值了
public static long get(int l, int r){
return h[r] - h[l-1]*p[r-l+1];
}
}
抱歉今天更新这么晚,花了太多不该花的时间,经历了没理解题->没理解核心公式->思路全理解了但是代码一直出bug,从晚上8点弄到现在终于AC,等我什么时候复习到这里的时候我再把讲解补上吧,太累了,睡了
声明:算法思路来源为y总,详细请见https://www.acwing.com/
本文仅用作学习记录和交流