Overview
String hashing converts strings to integers for O(1) substring comparison. It’s based on treating strings as polynomials and evaluating them at a chosen base.Static Hashing
- Build: O(n)
- Query: O(1)
- Update: Not supported
- Build: O(n log n)
- Query: O(1)
- Update: O(log n)
Hash Function
The polynomial rolling hash function:- Fast computation using prefix sums
- Efficient rolling hash for sliding windows
- Double hashing reduces collision probability
Static Hashing
For immutable strings with O(1) substring queries.Implementation
string_hashing_static_compress.cpp
Static Hashing Usage
- Substring Comparison
- Find Pattern
- Palindrome Check
Dynamic Hashing
Supports string modification with O(log n) updates using Fenwick tree.Implementation
string_hashing_dynamic_compress.cpp
Dynamic Hashing Usage
- String Modification
- Dynamic String Matching
- Text Editor Operations
Advanced Applications
Longest Common Substring
Distinct Substrings
Rolling Hash for Sliding Window
Collision Handling
Reducing Collisions:
- Use two large prime moduli (double hashing)
- Choose base > maximum character value
- Use moduli ~10^9 for 32-bit, ~10^18 for 64-bit
- Verify matches with direct comparison in critical cases
Best Practices
- Always use double hashing for competitive programming
- Precompute powers of base for efficiency
- Use 64-bit integers for hash values to avoid overflow
- Test with worst-case inputs to check for collisions
- Combine with binary search for optimization problems
- Cache frequently used hashes in maps/sets
Practice Problems
- Longest Duplicate Substring (LeetCode 1044)
- Distinct Echo Substrings (LeetCode 1316)
- Find K-Length Substrings With No Repeated Characters (LeetCode 1100)
- Substring with Concatenation of All Words (LeetCode 30)
- Palindrome Pairs (LeetCode 336)
See Also
- Pattern Matching - KMP, Rabin-Karp implementations
- Suffix Array - Alternative for pattern matching