AlgoMaster Logo

Repeated Substring Pattern

easyFrequency7 min readUpdated June 23, 2026

Understanding the Problem

We need to determine if the entire string s is made up of some shorter substring repeated two or more times. So if s = "abab", the answer is true because "ab" repeated twice gives us "abab". But if s = "aba", there is no substring we can repeat to get the original string.

The repeating substring must tile the string evenly, so its length must be a divisor of the total string length. If the string has length 6, the candidate substring could have length 1, 2, or 3, but not 4 or 5. The candidate length can also be at most n/2, since the string must hold at least two copies.

This divisibility constraint limits the search. We do not need to try every possible substring, only the ones whose lengths divide n evenly.

Key Constraints:

  • 1 <= s.length <= 10^4: With n up to 10,000, O(n^2) is feasible (100 million operations at worst). O(n * sqrt(n)) and O(n) are comfortable.
  • s consists of lowercase English letters: Standard character set, no special encoding concerns.

Approach 1: Brute Force (Check All Divisor Lengths)

Intuition

Try every possible substring length that could work, build the repeated string from it, and check whether it matches the original.

Since the repeating unit must tile the entire string, its length has to divide n evenly, and the string needs at least two copies, so the maximum candidate length is n/2. For each valid candidate length len, take the first len characters as the candidate substring, repeat it n/len times, and compare with s.

Algorithm

  1. Get the length n of the string.
  2. For each candidate length len from 1 to n/2:
    • If n % len != 0, skip this length (it cannot tile the string evenly).
    • Build the candidate by repeating s[0..len-1] exactly n/len times.
    • If the built string equals s, return true.
  3. If no candidate length worked, return false.

Example Walkthrough

Input:

0
a
1
b
2
a
3
b
s

Try len=1: candidate "a", repeat 4 times = "aaaa" != "abab". Skip.

Try len=2: candidate "ab", repeat 2 times = "abab" == "abab". Match!

true
result

Code

This builds a fresh string for each candidate length. The next approach detects repetition without constructing any candidate strings.

Approach 2: String Concatenation Trick

Intuition

If s is made of a repeating pattern, then concatenating s with itself to form s + s produces a doubled string in which the original s appears somewhere in the middle, not only at the start and end positions.

Take s = "abcabc". The repeating unit is "abc". Forming s + s = "abcabcabcabc" gives four copies of "abc" in a row. The original s appears starting at position 0 and at position 6 (the two endpoints), but it also appears starting at position 3, since positions 3 through 8 spell "abcabc".

If s has no repeating pattern, then s appears in s + s only at positions 0 and n, and nowhere in between.

The algorithm follows from this: form s + s, remove the first and last characters to destroy the two endpoint matches, and check whether s still appears in the result. If it does, the string has a repeating pattern.

Algorithm

  1. Concatenate s with itself to form doubled = s + s.
  2. Remove the first character and last character from doubled to get trimmed.
  3. If s is found as a substring within trimmed, return true.
  4. Otherwise, return false.

Example Walkthrough

1Start: s = "abab", form s + s = "abababab"
0
a
1
b
2
a
3
b
s (copy 1)
4
a
5
b
6
a
7
b
s (copy 2)
1/5

Code

This approach depends on the language's built-in substring search. The next approach detects the repeating period directly from the structure of the string, with a guaranteed linear bound.

Approach 3: KMP-Based (Failure Function)

Intuition

The KMP (Knuth-Morris-Pratt) algorithm's failure function reveals the internal repetitive structure of a string. The failure function for each position i stores the length of the longest proper prefix of s[0..i] that is also a suffix.

If a string of length n has a repeating pattern of length k, then the failure function value at the last position is n - k, that is, fail[n-1] = n - k. The string has a suffix of length n - k that matches a prefix of length n - k, and the remaining part (length k) is the repeating unit.

For this to represent a valid repeating pattern, k must divide n evenly. So the condition is: fail[n-1] > 0 (there is some prefix-suffix match) and n % (n - fail[n-1]) == 0 (the repeating unit length divides the string length).

Algorithm

  1. Build the KMP failure function array for the string s.
  2. Let failLast = fail[n-1], the failure function value at the last index.
  3. Compute the candidate pattern length: patternLen = n - failLast.
  4. If failLast > 0 and n % patternLen == 0, return true.
  5. Otherwise, return false.

Example Walkthrough

s
1Initialize: build failure function for s = "abcabcabc"
0
a
i=0
1
b
2
c
3
a
4
b
5
c
6
a
7
b
8
c
fail
1Initialize failure function array with zeros
0
0
1
0
2
0
3
0
4
0
5
0
6
0
7
0
8
0
1/6

Code