Most common substring of length X
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Substrings are contiguous sequences of characters within a string. In tasks involving string processing, one common requirement is to find the most frequent substring of a specified length X. This operation is fundamental in various domains including bioinformatics, natural language processing, data compression algorithms, and more. Understanding the most common substrings within a dataset can provide insights into data patterns, repetitions, or even anomalies.
Problem Definition
The problem can be summarized as finding the most frequently occurring substring of length X in a given string or dataset of strings. If there is a tie, all substrings with the maximum frequency may be considered.
Formal Representation
Given a string S of length N and an integer X, where X <= N:
- Generate all possible substrings of length
XfromS. - Count the occurrences of each substring.
- Return the substring(s) with the highest frequency.
Algorithms and Implementation
The process of finding the most common substring can be approached using different algorithms, each with varying efficiencies.
Naive Approach
The simplest way to solve this problem is a brute-force method:
- Generate substrings: Iterate through the string and generate all possible substrings of length
X. - Count occurrences: Use a dictionary to count how many times each substring occurs.
- Identify maximum: Iterate through the dictionary to find the substring(s) with the maximum count.
Complexity: This approach has a time complexity of due to the generation of substrings and requires additional space for frequency counting.
Optimized Approach: Rolling Hash
The rolling hash technique, which is used in algorithms like Rabin-Karp, can be employed to improve efficiency. Here's a high-level overview:
- Hash computation: Calculate the hash of the first substring of length
X. - Rolling update: Slide over the string to compute hashes of subsequent substrings, using the hash value of the previous substring to avoid redundant calculations.
- Count and compare: Use a dictionary to track the frequency of each hash and map it back to substrings.
Complexity: With a good hash function, rolling hash allows us to compute substring hashes in constant time, making the approach significantly more time-efficient compared to brute force, particularly for large N.
Example
Consider the string S = "ababcabab" with X = 2. The substrings generated and their frequencies are as follows:
- "ab": 3
- "ba": 2
- "bc": 1
- "ca": 1
The most common substring of length 2 is "ab".
Code Example
Below is a simple Python implementation using the naive approach:
Related reading
- Most efficient algorithm for merging sorted IEnumerableT
- Most efficient code for the first 10000 prime numbers?
- Most efficient method of generating a random number with a fixed number of bits set
- Most efficient sorting algorithm for a large set of numbers
- Most concise way to convert a SetT to a ListT
- most efficient method to use pandas pivot table over large file
- Most efficient way of randomly choosing a set of distinct integers
- Most efficient way to calculate Levenshtein distance

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 courseTrack 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.