Repetition of a substring n times

Last Updated : 24 May, 2026

Given a string s, the task is to check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. 

Examples: 

Input: s = "abcabcabc"
Output: true
Explanation: The given string is 3 times repetition of "abc"

Input: s = "abadabad"
Output: true
Explanation: The given string is 2 times repetition of "abad"

Input: s = "aabaabaabaab"
Output: true
Explanation: The given string is 4 times repetition of "aab"

Try It Yourself
redirect icon

Source: Google Interview Question 

[Naive Approach] Using Substring Repetition Check – O(n²) Time and O(n) Space

The idea is to try every possible substring length that can divide the original string length. For each valid length, we extract the substring and repeatedly concatenate it to form a new string. If the newly formed string becomes equal to the original string, then the given string is made by repeating that substring.

  • Try all substring lengths from 1 to n/2
  • Consider only lengths that exactly divide the string length
  • Extract the substring and repeat it required number of times
  • Compare the generated string with the original string and return result
C++
#include <iostream>
#include <string>

using namespace std;

bool isRepeat(string &s)
{
    int n = s.size();

    // try every possible substring length
    for(int len = 1; len <= n/2; len++)
    {
        // substring length must divide n
        if(n % len == 0)
        {
            string part = s.substr(0, len);

            string temp = "";

            int times = n / len;

            // repeat substring
            for(int i = 0; i < times; i++)
            {
                temp += part;
            }

            // check if formed string equals original
            if(temp == s)
            {
                return true;
            }
        }
    }

    return false;
}

int main()
{
    string s = "abcabcabc";

    if(isRepeat(s))
        cout << "True";
    else
        cout << "False";

    return 0;
}
Java
import java.util.*;

class GFG {

    static boolean isRepeat(String s)
    {
        int n = s.length();

        // try every possible substring length
        for(int len = 1; len <= n / 2; len++)
        {
            // substring length must divide n
            if(n % len == 0)
            {
                String part = s.substring(0, len);

                String temp = "";

                int times = n / len;

                // repeat substring
                for(int i = 0; i < times; i++)
                {
                    temp += part;
                }

                // check if formed string equals original
                if(temp.equals(s))
                {
                    return true;
                }
            }
        }

        return false;
    }

    public static void main(String[] args)
    {
        String s = "abcabcabc";

        if(isRepeat(s))
            System.out.println("True");
        else
            System.out.println("False");
    }
}
Python
def isRepeat(s):

    n = len(s)

    # try every possible substring length
    for length in range(1, n // 2 + 1):

        # substring length must divide n
        if n % length == 0:

            part = s[0:length]

            temp = ""

            times = n // length

            # repeat substring
            for i in range(times):

                temp += part

            # check if formed string equals original
            if temp == s:

                return True

    return False


s = "abcabcabc"

if isRepeat(s):
    print("True")

else:
    print("False")
C#
using System;

class GFG {

    static bool isRepeat(string s)
    {
        int n = s.Length;

        // try every possible substring length
        for(int len = 1; len <= n / 2; len++)
        {
            // substring length must divide n
            if(n % len == 0)
            {
                string part = s.Substring(0, len);

                string temp = "";

                int times = n / len;

                // repeat substring
                for(int i = 0; i < times; i++)
                {
                    temp += part;
                }

                // check if formed string equals original
                if(temp == s)
                {
                    return true;
                }
            }
        }

        return false;
    }

    static void Main()
    {
        string s = "abcabcabc";

        if(isRepeat(s))
            Console.WriteLine("True");
        else
            Console.WriteLine("False");
    }
}
JavaScript
function isRepeat(s)
{
    let n = s.length;

    // try every possible substring length
    for(let len = 1; len <= Math.floor(n / 2); len++)
    {
        // substring length must divide n
        if(n % len == 0)
        {
            let part = s.substring(0, len);

            let temp = "";

            let times = Math.floor(n / len);

            // repeat substring
            for(let i = 0; i < times; i++)
            {
                temp += part;
            }

            // check if formed string equals original
            if(temp == s)
            {
                return true;
            }
        }
    }

    return false;
}

let s = "abcabcabc";

if(isRepeat(s))
    console.log("True");

else
    console.log("False");

Output
True

[Efficient Approach] Using KMP (LPS Array) – O(n) Time and O(n) Space

The idea is to use the Longest Prefix Suffix (LPS) array from the KMP algorithm. If a string is formed by repeating one of its substrings, then the string will have a proper prefix that is also a suffix. The last value of the LPS array gives the length of this repeating pattern. Using this value, we check whether the remaining substring length divides the total string length completely.

  • Construct the LPS array for the given string using KMP preprocessing
  • Find the length of the longest proper prefix which is also a suffix
  • Compute the repeating substring length using n - lps[n-1]
  • If the string length is divisible by this value, return true otherwise false


Why does this work?

Let us consider the two cases.

  • String is actually a repetition : Then a large part of the prefix appears again at the end therefore LPS of last character becomes large. If there are exactly two repetitions, then there would not be any overlapping in prefix and suffix. Otherwise there would be an overlapping part in the common part of suffix and prefix. In both the cases, we get length of the repeating substring by subtracting LPS of last from total length.
  • String is not a repetition : There are two cases here. If the LPS of last character is 0, then string is definitely not a repitiion. If LPS is not 0, for example, bbxxbb has LPS 2. In this case there is no common part which we check by checking divisibility of total length - LPS with the total length.

C++
#include <iostream>
#include <vector>
#include <string>

using namespace std;

// A utility function to fill lps[] or compute prefix
// function used in KMP string matching algorithm.
void computeLPSArray(string &s, int n, vector<int>& lps)
{
    // length of the previous longest prefix suffix
    int len = 0;

    int i;

    lps[0] = 0; // lps[0] is always 0

    i = 1;

    // the loop calculates lps[i] for i = 1 to n-1
    while (i < n) {

        if (s[i] == s[len]) {

            len++;

            lps[i] = len;

            i++;
        }

        else // (s[i] != s[len])
        {
            if (len != 0) {

                // This is tricky. Consider the example
                // AAACAAAA and i = 7.
                len = lps[len - 1];

                // Also, note that we do not increment i
                // here
            }

            else // if (len == 0)
            {
                lps[i] = 0;

                i++;
            }
        }
    }
}

// Returns true if s is repetition of one of its
// substrings else return false.
bool isRepeat(string &s)
{
    // Find length of string and create an array to
    // store lps values used in KMP
    int n = s.length();

    vector<int> lps(n);

    // Preprocess the pattern (calculate lps[] array)
    computeLPSArray(s, n, lps);

    // Find length of longest suffix which is also
    // prefix of s.
    int len = lps[n - 1];

    // If there exist a suffix which is also prefix AND
    // Length of the remaining substring divides total
    // length, then s[0..n-len-1] is the substring that
    // repeats n/(n-len) times
    return (len > 0 && n % (n - len) == 0) ? true : false;
}

// Driver program to test above function
int main()
{
    string s = "ABCABC";

    isRepeat(s) ? cout << "True"
                : cout << "False";

    return 0;
}
Java
import java.util.*;

class GFG {

    // A utility function to fill lps[] or compute prefix
    // function used in KMP string matching algorithm.
    static void computeLPSArray(String s, int n, int[] lps)
    {
        // length of the previous longest prefix suffix
        int len = 0;

        int i;

        lps[0] = 0; // lps[0] is always 0

        i = 1;

        // the loop calculates lps[i] for i = 1 to n-1
        while (i < n) {

            if (s.charAt(i) == s.charAt(len)) {

                len++;

                lps[i] = len;

                i++;
            }

            else // (s[i] != s[len])
            {
                if (len != 0) {

                    // This is tricky. Consider the example
                    // AAACAAAA and i = 7.
                    len = lps[len - 1];

                    // Also, note that we do not increment i
                    // here
                }

                else // if (len == 0)
                {
                    lps[i] = 0;

                    i++;
                }
            }
        }
    }

    // Returns true if s is repetition of one of its
    // substrings else return false.
    static boolean isRepeat(String s)
    {
        // Find length of string and create an array to
        // store lps values used in KMP
        int n = s.length();

        int[] lps = new int[n];

        // Preprocess the pattern (calculate lps[] array)
        computeLPSArray(s, n, lps);

        // Find length of longest suffix which is also
        // prefix of s.
        int len = lps[n - 1];

        // If there exist a suffix which is also prefix AND
        // Length of the remaining substring divides total
        // length, then s[0..n-len-1] is the substring that
        // repeats n/(n-len) times
        return (len > 0 && n % (n - len) == 0) ? true : false;
    }

    // Driver program to test above function
    public static void main(String[] args)
    {
        String s = "ABCABC";

        System.out.println(isRepeat(s) ? "True"
                                       : "False");
    }
}

// This code is contributed by Aditya Kumar (adityakumar129)
Python
# A utility function to fill lps[] or compute prefix
# function used in KMP string matching algorithm.
def computeLPSArray(s, n, lps):

    # length of the previous longest prefix suffix
    length = 0

    lps[0] = 0  # lps[0] is always 0

    i = 1

    # the loop calculates lps[i] for i = 1 to n-1
    while i < n:

        if s[i] == s[length]:

            length += 1

            lps[i] = length

            i += 1

        else:  # (s[i] != s[len])

            if length != 0:

                # This is tricky. Consider the example
                # AAACAAAA and i = 7.
                length = lps[length - 1]

                # Also, note that we do not increment i
                # here

            else:  # if (len == 0)

                lps[i] = 0

                i += 1


# Returns true if s is repetition of one of its
# substrings else return false.
def isRepeat(s):

    # Find length of string and create an array to
    # store lps values used in KMP
    n = len(s)

    lps = [0] * n

    # Preprocess the pattern (calculate lps[] array)
    computeLPSArray(s, n, lps)

    # Find length of longest suffix which is also
    # prefix of s.
    length = lps[n - 1]

    # If there exist a suffix which is also prefix AND
    # Length of the remaining substring divides total
    # length, then s[0..n-len-1] is the substring that
    # repeats n/(n-len) times
    return True if (length > 0 and
                    n % (n - length) == 0) else False


# Driver program to test above function
s = "ABCABC"

print("True" if isRepeat(s)
      else "False")
C#
using System;

class GFG {

    // A utility function to fill lps[] or compute prefix
    // function used in KMP string matching algorithm.
    static void computeLPSArray(string s, int n, int[] lps)
    {
        // length of the previous longest prefix suffix
        int len = 0;

        int i;

        lps[0] = 0; // lps[0] is always 0

        i = 1;

        // the loop calculates lps[i] for i = 1 to n-1
        while (i < n) {

            if (s[i] == s[len]) {

                len++;

                lps[i] = len;

                i++;
            }

            else // (s[i] != s[len])
            {
                if (len != 0) {

                    // This is tricky. Consider the example
                    // AAACAAAA and i = 7.
                    len = lps[len - 1];

                    // Also, note that we do not increment i
                    // here
                }

                else // if (len == 0)
                {
                    lps[i] = 0;

                    i++;
                }
            }
        }
    }

    // Returns true if s is repetition of one of its
    // substrings else return false.
    static bool isRepeat(string s)
    {
        // Find length of string and create an array to
        // store lps values used in KMP
        int n = s.Length;

        int[] lps = new int[n];

        // Preprocess the pattern (calculate lps[] array)
        computeLPSArray(s, n, lps);

        // Find length of longest suffix which is also
        // prefix of s.
        int len = lps[n - 1];

        // If there exist a suffix which is also prefix AND
        // Length of the remaining substring divides total
        // length, then s[0..n-len-1] is the substring that
        // repeats n/(n-len) times
        return (len > 0 && n % (n - len) == 0) ? true : false;
    }

    // Driver program to test above function
    static void Main()
    {
        string s = "ABCABC";

        Console.WriteLine(isRepeat(s) ? "True"
                                      : "False");
    }
}
JavaScript
// A utility function to fill lps[] or compute prefix
// function used in KMP string matching algorithm.
function computeLPSArray(s, n, lps)
{
    // length of the previous longest prefix suffix
    let len = 0;

    lps[0] = 0; // lps[0] is always 0

    let i = 1;

    // the loop calculates lps[i] for i = 1 to n-1
    while (i < n) {

        if (s[i] == s[len]) {

            len++;

            lps[i] = len;

            i++;
        }

        else // (s[i] != s[len])
        {
            if (len != 0) {

                // This is tricky. Consider the example
                // AAACAAAA and i = 7.
                len = lps[len - 1];

                // Also, note that we do not increment i
                // here
            }

            else // if (len == 0)
            {
                lps[i] = 0;

                i++;
            }
        }
    }
}

// Returns true if s is repetition of one of its
// substrings else return false.
function isRepeat(s)
{
    // Find length of string and create an array to
    // store lps values used in KMP
    let n = s.length;

    let lps = new Array(n).fill(0);

    // Preprocess the pattern (calculate lps[] array)
    computeLPSArray(s, n, lps);

    // Find length of longest suffix which is also
    // prefix of s.
    let len = lps[n - 1];

    // If there exist a suffix which is also prefix AND
    // Length of the remaining substring divides total
    // length, then s[0..n-len-1] is the substring that
    // repeats n/(n-len) times
    return (len > 0 && n % (n - len) == 0) ? true : false;
}

// Driver program to test above function
let s = "ABCABC";

console.log(isRepeat(s) ? "True"
                        : "False");

Output
True
Comment