![]() |
VOOZH | about |
Given two strings A, B and some queries consisting of an integer i, the task is to check whether the sub-string of A starting from index i and ending at index i + length(B) - 1 equals B or not. If equal then print Yes else print No. Note that i + length(B) will always be smaller than length(A).
Examples:
Input: A = "abababa", B = "aba", q[] = {0, 1, 2, 3}
Output:
Yes
No
Yes
No
a[0-2] = "aba" = b (both are equal)
a[1-3] = "bab" != b
a[2-4] = "aba" = b
a[3-5] = "bab" !=bInput: A = "GeeksForGeeks", B = "Geeks", q[] = {0, 5, 8}
Output:
Yes
No
Yes
A simple approach will be to compare the strings character by character for every query which will take O(length(B)) time to answer each query.
Efficient approach: We will optimize the query processing using rolling hash algorithm.
First, we will find hash value of string B. Then, using rolling hash technique, we will do the pre-processing of string A.
Let's suppose we created an array hash_A. Then ith element of this array will store.
((a[0] - 97) + (a[1] - 97) * d + (a[2] - 97) * d2 + ..... + (a[i] - 97) * di) % mod
where d is the multiplier in rolling-hash.
We will use this to find hash of the sub-string of A.
Hash of sub-string of A starting from i can be found as (hash_a[i + len_b - 1] - hash_a[i - 1]) / di or more specifically
((hash_a[i + len_b - 1] - hash_a[i - 1] + 2 * mod) * mi(di)) % mod
Thus, using this we can answer each query in O(1).
Below is the implementation of the above approach:
Yes No Yes No
Time Complexity: O(N*Q)
Auxiliary Space: O(M*N)
Note: For simplicity, we have used only one hash function. Use double/triple hash to eliminate any chance of collision and more accurate result.
The above question can be solved by using DP also, below is the java code.
true false true
Time Complexity: O(M*N)
Auxiliary Space: O(M*N)