2
public String subStrHash(String s, int power, int modulo, int k, int hashValue) {3
// calculate all the powers from power^0 till power^k4
// utilized binary exponentiation5
long[] powers = new long[k];6
for (int i = 0; i < k; i++) powers[i] = binaryExponentiation(power, i, modulo);8
// pre compute the initial hash from behind.9
// I have explained at top you why traversing from behind is easy10
long currentHashValue = 0;11
int index = s.length() - 1;12
int powerIndex = k - 1;13
while (index >= s.length() - k) {14
// (a+b) % modulo = ( (a % modulo) + (b % modulo) ) % modulo;15
// do it for k times from behind17
((s.charAt(index--) - 'a' + 1) % modulo * powers[powerIndex--] % modulo) % modulo;19
currentHashValue %= modulo;22
if (currentHashValue == hashValue) {23
startIndex = s.length() - k;26
// I have pre computed already for k values from behind. so start from (length of S - k - 1)27
// Let's take an example of "leetcode" itself28
// "de" is pre computed29
// point is to add one character from behind and remove one from end (Sliding from back to31
// Modular Arithmetic for (a-b) % modulo = ( (a % modulo) - (b % modulo) + modulo) % modulo;32
// keep tracking of the start index if hash value matches. That's it.33
for (int i = s.length() - k - 1; i >= 0; i--) {34
// below line a --> currentHashValue35
// below line b --> (s.charAt(i+k) - 'a' + 1 * powers[k-1])37
((currentHashValue % modulo)38
- (((s.charAt(i + k) - 'a' + 1) * powers[k - 1]) % modulo)41
// we need to multiply a power once for all43
currentHashValue = currentHashValue * power;44
// Modular Arithmetic for (a+b) % modulo is below line45
currentHashValue = (currentHashValue % modulo + (s.charAt(i) - 'a' + 1) % modulo) % modulo;47
if (currentHashValue == hashValue) {51
return s.substring(startIndex, startIndex + k);54
private long binaryExponentiation(long a, long b, long mod) {58
if (b % 2 == 1) result = result * a % mod;