Welcome to Subscribe On Youtube
2156. Find Substring With Given Hash Value
Description
The hash of a 0-indexed string s
of length k
, given integers p
and m
, is computed using the following function:
hash(s, p, m) = (val(s[0]) * p0 + val(s[1]) * p1 + ... + val(s[k-1]) * pk-1) mod m
.
Where val(s[i])
represents the index of s[i]
in the alphabet from val('a') = 1
to val('z') = 26
.
You are given a string s
and the integers power
, modulo
, k
, and hashValue.
Return sub
, the first substring of s
of length k
such that hash(sub, power, modulo) == hashValue
.
The test cases will be generated such that an answer always exists.
A substring is a contiguous non-empty sequence of characters within a string.
Example 1:
Input: s = "leetcode", power = 7, modulo = 20, k = 2, hashValue = 0 Output: "ee" Explanation: The hash of "ee" can be computed to be hash("ee", 7, 20) = (5 * 1 + 5 * 7) mod 20 = 40 mod 20 = 0. "ee" is the first substring of length 2 with hashValue 0. Hence, we return "ee".
Example 2:
Input: s = "fbxzaad", power = 31, modulo = 100, k = 3, hashValue = 32 Output: "fbx" Explanation: The hash of "fbx" can be computed to be hash("fbx", 31, 100) = (6 * 1 + 2 * 31 + 24 * 312) mod 100 = 23132 mod 100 = 32. The hash of "bxz" can be computed to be hash("bxz", 31, 100) = (2 * 1 + 24 * 31 + 26 * 312) mod 100 = 25732 mod 100 = 32. "fbx" is the first substring of length 3 with hashValue 32. Hence, we return "fbx". Note that "bxz" also has a hash of 32 but it appears later than "fbx".
Constraints:
1 <= k <= s.length <= 2 * 104
1 <= power, modulo <= 109
0 <= hashValue < modulo
s
consists of lowercase English letters only.- The test cases are generated such that an answer always exists.
Solutions
-
/** * @param {string} s * @param {number} power * @param {number} modulo * @param {number} k * @param {number} hashValue * @return {string} */ var subStrHash = function (s, power, modulo, k, hashValue) { power = BigInt(power); modulo = BigInt(modulo); hashValue = BigInt(hashValue); const n = s.length; let pk = 1n; let ac = 0n; // 倒序滑动窗口 for (let i = n - 1; i > n - 1 - k; i--) { ac = (ac * power + getCode(s, i)) % modulo; pk = (pk * power) % modulo; } let ans = -1; if (ac == hashValue) { ans = n - k; } for (let i = n - 1 - k; i >= 0; i--) { let pre = (getCode(s, i + k) * pk) % modulo; ac = (ac * power + getCode(s, i) - pre + modulo) % modulo; if (ac == hashValue) { ans = i; } } return ans == -1 ? '' : s.substring(ans, ans + k); }; function getCode(str, index) { return BigInt(str.charCodeAt(index) - 'a'.charCodeAt(0) + 1); }
-
class Solution { public String subStrHash(String s, int power, int modulo, int k, int hashValue) { long h = 0, p = 1; int n = s.length(); for (int i = n - 1; i >= n - k; --i) { int val = s.charAt(i) - 'a' + 1; h = ((h * power % modulo) + val) % modulo; if (i != n - k) { p = p * power % modulo; } } int j = n - k; for (int i = n - k - 1; i >= 0; --i) { int pre = s.charAt(i + k) - 'a' + 1; int cur = s.charAt(i) - 'a' + 1; h = ((h - pre * p % modulo + modulo) * power % modulo + cur) % modulo; if (h == hashValue) { j = i; } } return s.substring(j, j + k); } }
-
class Solution { public: string subStrHash(string s, int power, int modulo, int k, int hashValue) { long long h = 0, p = 1; int n = s.size(); for (int i = n - 1; i >= n - k; --i) { int val = s[i] - 'a' + 1; h = ((h * power % modulo) + val) % modulo; if (i != n - k) { p = p * power % modulo; } } int j = n - k; for (int i = n - k - 1; i >= 0; --i) { int pre = s[i + k] - 'a' + 1; int cur = s[i] - 'a' + 1; h = ((h - pre * p % modulo + modulo) * power % modulo + cur) % modulo; if (h == hashValue) { j = i; } } return s.substr(j, k); } };
-
class Solution: def subStrHash( self, s: str, power: int, modulo: int, k: int, hashValue: int ) -> str: h, n = 0, len(s) p = 1 for i in range(n - 1, n - 1 - k, -1): val = ord(s[i]) - ord("a") + 1 h = ((h * power) + val) % modulo if i != n - k: p = p * power % modulo j = n - k for i in range(n - 1 - k, -1, -1): pre = ord(s[i + k]) - ord("a") + 1 cur = ord(s[i]) - ord("a") + 1 h = ((h - pre * p) * power + cur) % modulo if h == hashValue: j = i return s[j : j + k]
-
func subStrHash(s string, power int, modulo int, k int, hashValue int) string { h, p := 0, 1 n := len(s) for i := n - 1; i >= n-k; i-- { val := int(s[i] - 'a' + 1) h = (h*power%modulo + val) % modulo if i != n-k { p = p * power % modulo } } j := n - k for i := n - k - 1; i >= 0; i-- { pre := int(s[i+k] - 'a' + 1) cur := int(s[i] - 'a' + 1) h = ((h-pre*p%modulo+modulo)*power%modulo + cur) % modulo if h == hashValue { j = i } } return s[j : j+k] }
-
function subStrHash( s: string, power: number, modulo: number, k: number, hashValue: number, ): string { let h: bigint = BigInt(0), p: bigint = BigInt(1); const n: number = s.length; const mod = BigInt(modulo); for (let i: number = n - 1; i >= n - k; --i) { const val: bigint = BigInt(s.charCodeAt(i) - 'a'.charCodeAt(0) + 1); h = (((h * BigInt(power)) % mod) + val) % mod; if (i !== n - k) { p = (p * BigInt(power)) % mod; } } let j: number = n - k; for (let i: number = n - k - 1; i >= 0; --i) { const pre: bigint = BigInt(s.charCodeAt(i + k) - 'a'.charCodeAt(0) + 1); const cur: bigint = BigInt(s.charCodeAt(i) - 'a'.charCodeAt(0) + 1); h = ((((h - ((pre * p) % mod) + mod) * BigInt(power)) % mod) + cur) % mod; if (Number(h) === hashValue) { j = i; } } return s.substring(j, j + k); }