string manipulation
substrings
algorithm
computer science
programming

Finding out whether there exist two identical substrings one next to another

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Understanding the Problem

Finding adjacent identical substrings in a string is a common problem in computer science, often encountered in text processing or pattern matching tasks. The goal is to determine if a string contains any two identical substrings that are contiguous. In other words, we're looking for a pattern "XX" where "X" is any non-empty substring.

Technical Description

Given a string `S` of length `n`, the task is to check if there exist two non-empty substrings `S[i:j]` and `S[j:k]` such that `S[i:j] == S[j:k]` and `j = k - (j-i)`, which implies the substrings are adjacent. The complexity of directly checking all possible pairs of substrings can be overwhelming, especially for longer strings, since a naive approach would take O(n3)O(n^3) time.

Efficient Algorithm

To solve this problem efficiently, a useful approach involves using rolling hashing—a technique that allows comparing strings in a constant time after pre-processing. Here's how we can implement it:

  1. Hash Function: Calculate a hash value for strings based on an arbitrary but large base (often a prime number, such as 31 or 101) and perform modulus operation with another large prime to avoid overflow. This hash can be represented as: hash(S)=(S[0]×basen1+S[1]×basen2++S[n1]×base0)modmodulus\text{hash}(S) = (S[0] \times \text{base}^{n-1} + S[1] \times \text{base}^{n-2} + \ldots + S[n-1] \times \text{base}^0) \bmod \text{modulus}
  2. Rolling Hash: As you move along the string, compute the hash dynamically using the previous hash value—a concept similar to a sliding window: new_hash=(old_hashSleft×baseL1)×base+Sright\text{new\_hash} = (\text{old\_hash} - S_{\text{left}} \times \text{base}^{L-1}) \times \text{base} + S_{\text{right}} Here, SleftS_{\text{left}} is the character going out of the window, and SrightS_{\text{right}} is the character coming in.
  3. Implementation Steps: • Calculate the hash for the first substring of length `len`. • Slide the window of length `len` through the string, updating hash values using the rolling hash formula. • Check for hash collisions; if two adjacent substrings have the same hash, compare them directly to confirm they're identical (to avoid false positives due to hash collisions).
  4. Edge Cases: Be sure to consider strings with special characters or non-Alphabetical inputs, and adjust the base and modulus to prevent hash collision probabilities.

Example

Consider the string `S = "abcabcx"`, and you want to check substrings of length 3:

  1. Calculate the initial hash of `abc` as described.
  2. As the window slides, you'll compare hash for `abc` and `cab`.
  3. When the window reaches `abcx`, hash of `abc` after `c` matches the first window hash, confirming they are identical.

Additional Considerations

Complexity Analysis

Using rolling hashes, the time complexity turns into O(nlogn)O(n \cdot \log n) to find a solution by checking all possible window sizes (using binary search over lengths) up to the string's half-length.

Applications

Text Editors: Detect duplicate consecutive blocks of text. • Compression Algorithms: Identify redundancy very quickly for optimization. • DNA Sequencing: Find repeat patterns in sequences for biological research.

Table: Key Points Summary

ConceptDescription
ProblemFinding identical adjacent substrings
Naive AlgorithmO(n3)O(n^3) complexity with direct pair checks
Efficient ApproachRolling hashes with O(nlogn)O(n \log n) complexity
Hash FunctionBased on base-prime combinations for uniqueness
ApplicationsText editing, data compression, and DNA analysis
ToolsRolling hash, direct substring comparison, window sliding
Edge CasesHandle special characters and large strings

This algorithm efficiently finds adjacent identical substrings, offering optimized performance through rolling hash methods while being versatile enough to handle a wide range of applications across computational disciplines.


Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.