LC-6356.子字符串异或查询
题目描述
给你一个 二进制字符串 s 和一个整数数组 queries ,其中 queries[i] = [firsti, secondi] 。
对于第 i 个查询,找到 s 的 最短子字符串 ,它对应的 十进制值 val 与 firsti 按位异或 得到 secondi ,换言之,val ^ firsti == secondi 。
第 i 个查询的答案是子字符串 [lefti, righti] 的两个端点(下标从 0 开始),如果不存在这样的子字符串,则答案为 [-1, -1] 。如果有多个答案,请你选择 lefti 最小的一个。
请你返回一个数组 ans ,其中 ans[i] = [lefti, righti] 是第 i 个查询的答案。
子字符串 是一个字符串中一段连续非空的字符序列。
示例1:
1 |
|
提示1:
1 |
|
预处理
题目 $val \oplus first = second$ 可以转化成 $val = first \oplus second$,此时我们对每个询问可以直接计算出对应的 $val$ ,再判断该 $val$ 是否为原字符串的一个子串即可。
但是注意到 $queries.length <= 10^5, s.length <= 10 ^4$ ,也就是说就算使用 KMP
算法 $O(n + m)$ 的判断子串也会超时。
一个关键的部分是 $0 <= firsti, secondi <= 10^9$ ,所以他们的异或结果的二进制表示不会超过 $30$ 位,那么我们就可以预处理出原字符串所有小于等于 $30$ 长度的子串及其对应下标的映射关系,后面的询问过程就只需直接查询结果即可,此时时间复杂度为 $O(30N + M)$ 。
1 |
|
LC-6356.子字符串异或查询
https://wecgwm.github.io/2023/02/12/LC-6356-子字符串异或查询/