Find if a given string can be represented from a substring by iterating the substring “n” times - GeeksforGeeks

09 May, 2022
Given a string ‘str’, check if it can be constructed by taking a substring of it and appending multiple copies of the substring together.
Examples: 
Input: str = "abcabcabc"
Output: true
The given string is 3 times repetition of "abc"

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

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

Input: str = "abcdabc"
Output: false
Source: Google Interview Question 
There can be many solutions to this problem. The challenging part is to solve the problem in O(n) time. Below is a O(n) algorithm.
Let the given string be ‘str’ and length of given string be ‘n’.1) Find the length of the longest proper prefix of ‘str’ which is also a suffix. Let the length of the longest proper prefix suffix be ‘len’. This can be computed in O(n) time using pre-processing step of KMP string matching algorithm.2) If value of ‘n – len’ divides n (or ‘n % (n-len)’ is 0), then return true, else return false.In case of ‘true’ , the substring ‘str[0..n-len-1]’ is the substring that repeats n/(n-len) times.
Let us take few examples.Input: str = “ABCDABCD”, n = 8 (Number of characters in ‘str’) The value of len is 4 (“ABCD” is the longest substring which is both prefix and suffix) Since (n-len) divides n, the answer is true.Input: str = “ABCDABC”, n = 7 (Number of characters in ‘str’) The value of len is 3 (“ABC” is the longest substring which is both prefix and suffix) Since (n-len) doesn’t divides n, the answer is false.Input: str = “ABCABCABCABCABC”, n = 15 (Number of characters in ‘str’) The value of len is 12 (“ABCABCABCABC” is the longest substring which is both prefix and suffix) Since (n-len) divides n, the answer is true.
How does this work? length of longest proper prefix-suffix (or len) is always between 0 to n-1. If len is n-1, then all characters in string are same. For example len is 3 for “AAAA”. If len is n-2 and n is even, then two characters in string repeat n/2 times. For example “ABABABAB”, length of lps is 6. The reason is if the first n-2 characters are same as last n-2 character, the starting from the first pair, every pair of characters is identical to the next pair. The following diagram demonstrates same for substring of length 4.
Following is the implementation of above algorithm: 
C++
C
Java
Python3
C#
Javascript
// A C++ program to check if a string is 'n' times// repetition of one of its substrings#include <bits/stdc++.h>using namespace std; // A utility function to fill lps[] or compute prefix// function used in KMP string matching algorithm. Refer// https://www.geeksforgeeks.org/archives/11902 for// detailsvoid computeLPSArray(char str[], int M, 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 M-1    while (i < M) {        if (str[i] == str[len]) {            len++;            lps[i] = len;            i++;        }        else // (pat[i] != pat[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 str is repetition of one of its// substrings else return false.bool isRepeat(char str[]){    // Find length of string and create an array to    // store lps values used in KMP    int n = strlen(str);    int lps[n];     // Preprocess the pattern (calculate lps[] array)    computeLPSArray(str, n, lps);     // Find length of longest suffix which is also    // prefix of str.    int len = lps[n - 1];     // If there exist a suffix which is also prefix AND    // Length of the remaining substring divides total    // length, then str[0..n-len-1] is the substring that    // repeats n/(n-len) times (Readers can print substring    // and value of n/(n-len) for more clarity.    return (len > 0 && n % (n - len) == 0) ? true : false;} // Driver program to test above functionint main(){    char txt[][100]        = { "ABCABC",        "ABABAB",   "ABCDABCD",            "GEEKSFORGEEKS", "GEEKGEEK", "AAAACAAAAC",            "ABCDABC" };    int n = sizeof(txt) / sizeof(txt[0]);    for (int i = 0; i < n; i++)        isRepeat(txt[i]) ? cout << "True\n"                         : cout << "False\n";    return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// A C++ program to check if a string is 'n' times// repetition of one of its substrings#include <stdbool.h>#include <stdio.h>#include <string.h> // A utility function to fill lps[] or compute prefix// function used in KMP string matching algorithm. Refer// https://www.geeksforgeeks.org/archives/11902 for// detailsvoid computeLPSArray(char str[], int M, 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 M-1    while (i < M) {        if (str[i] == str[len]) {            len++;            lps[i] = len;            i++;        }        else // (pat[i] != pat[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 str is repetition of one of its// substrings else return false.bool isRepeat(char str[]){    // Find length of string and create an array to    // store lps values used in KMP    int n = strlen(str);    int lps[n];     // Preprocess the pattern (calculate lps[] array)    computeLPSArray(str, n, lps);     // Find length of longest suffix which is also    // prefix of str.    int len = lps[n - 1];     // If there exist a suffix which is also prefix AND    // Length of the remaining substring divides total    // length, then str[0..n-len-1] is the substring that    // repeats n/(n-len) times (Readers can print substring    // and value of n/(n-len) for more clarity.    return (len > 0 && n % (n - len) == 0) ? true : false;} // Driver program to test above functionint main(){    char txt[][100]        = { "ABCABC",        "ABABAB",   "ABCDABCD",            "GEEKSFORGEEKS", "GEEKGEEK", "AAAACAAAAC",            "ABCDABC" };    int n = sizeof(txt) / sizeof(txt[0]);    for (int i = 0; i < n; i++)        isRepeat(txt[i]) ? printf("True\n")                         : printf("False\n");    return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// Java program to check if a string is 'n'// times repetition of one of its substringsimport java.io.*;class GFG {     // A utility function to fill lps[] or compute    // prefix function used in KMP string matching    // algorithm. Refer    // https://www.geeksforgeeks.org/archives/11902    // for details    static void computeLPSArray(String str, int M,                                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 M-1        while (i < M) {            if (str.charAt(i) == str.charAt(len)) {                len++;                lps[i] = len;                i++;            }            else // (pat[i] != pat[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 str is repetition of    // one of its substrings else return false.    static boolean isRepeat(String str)    {        // Find length of string and create        // an array to store lps values used in KMP        int n = str.length();        int lps[] = new int[n];         // Preprocess the pattern (calculate lps[] array)        computeLPSArray(str, n, lps);         // Find length of longest suffix        // which is also prefix of str.        int len = lps[n - 1];         // If there exist a suffix which is also        // prefix AND Length of the remaining substring        // divides total length, then str[0..n-len-1]        // is the substring that repeats n/(n-len)        // times (Readers can print substring and        // value of n/(n-len) for more clarity.        return (len > 0 && n % (n - len) == 0) ? true                                               : false;    }     // Driver program to test above function    public static void main(String[] args)    {        String txt[]            = { "ABCABC",        "ABABAB",   "ABCDABCD",                "GEEKSFORGEEKS", "GEEKGEEK", "AAAACAAAAC",                "ABCDABC" };        int n = txt.length;        for (int i = 0; i < n; i++) {            if (isRepeat(txt[i]) == true)                System.out.println("True");            else                System.out.println("False");        }    }} // This code is contributed by Aditya Kumar (adityakumar129)
# A Python program to check if a string is 'n' times# repetition of one of its substrings # A utility function to fill lps[] or compute prefix function# used in KMP string matching algorithm. Refer# https://www.geeksforgeeks.org/archives/11902 for detailsdef computeLPSArray(string, M, lps):    length = 0        # length of the previous longest prefix suffix    i = 1     lps[0] = 0    # lps[0] is always 0     # the loop calculates lps[i] for i = 1 to M-1    while i < M:        if string[i] == string[length]:            length += 1            lps[i] = length            i += 1        else:            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:                lps[i] = 0                i += 1 # Returns true if string is repetition of one of its substrings# else return false.def isRepeat(string):    # Find length of string and create an array to    # store lps values used in KMP    n = len(string)    lps = [0] * n     # Preprocess the pattern (calculate lps[] array)    computeLPSArray(string, n, lps)     # Find length of longest suffix which is also    # prefix of str.    length = lps[n-1]     # If there exist a suffix which is also prefix AND    # Length of the remaining substring divides total    # length, then str[0..n-len-1] is the substring that    # repeats n/(n-len) times (Readers can print substring    # and value of n/(n-len) for more clarity.    if length > 0 and n%(n-length) == 0:        return True    else:        False # Driver programtxt = ["ABCABC", "ABABAB", "ABCDABCD", "GEEKSFORGEEKS",        "GEEKGEEK", "AAAACAAAAC", "ABCDABC"]n = len(txt)for i in range(n):    if isRepeat(txt[i]):        print (True)    else:        print (False) # This code is contributed by BHAVYA JAIN
// C# program to check if a string is 'n'// times repetition of one of its substringsusing System; class GFG {         // A utility function to fill lps[] or    // compute prefix function used in KMP    // string matching algorithm. Refer    // https://www.geeksforgeeks.org/archives/11902    // for details    static void computeLPSArray(String str, int M,                                         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 M-1        while (i < M)        {            if (str[i] == str[len])            {                len++;                lps[i] = len;                i++;            }            else // (pat[i] != pat[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 str is repetition of    // one of its substrings else return false.    static bool isRepeat(String str)    {                 // Find length of string and create        // an array to store lps values used        // in KMP        int n = str.Length;        int[] lps = new int[n];             // Preprocess the pattern (calculate        // lps[] array)        computeLPSArray(str, n, lps);             // Find length of longest suffix        // which is also prefix of str.        int len = lps[n-1];         // If there exist a suffix which is also        // prefix AND Length of the remaining        // substring divides total length, then        // str[0..n-len-1] is the substring that        // repeats n/(n-len) times (Readers can        // print substring and value of n/(n-len)        // for more clarity.        return (len > 0 && n % (n - len) == 0)                               ? true : false;    }         // Driver program to test above function    public static void Main()    {        String[] txt = {"ABCABC", "ABABAB",                    "ABCDABCD", "GEEKSFORGEEKS",                       "GEEKGEEK", "AAAACAAAAC",                                     "ABCDABC"};        int n = txt.Length;                 for (int i = 0; i < n; i++)        {            if(isRepeat(txt[i]) == true)                Console.WriteLine("True");            else                Console.WriteLine("False");        }    }} // This code is contributed by Sam007.
<script>     // Javascript program to check if a string is 'n'    // times repetition of one of its substrings         // A utility function to fill lps[] or    // compute prefix function used in KMP    // string matching algorithm. Refer    // https://www.geeksforgeeks.org/archives/11902    // for details    function computeLPSArray(str, M, lps)    {                   // length of the previous        // longest prefix suffix        let len = 0;                   let i;               lps[0] = 0; // lps[0] is always 0        i = 1;               // the loop calculates lps[i]        // for i = 1 to M-1        while (i < M)        {            if (str[i] == str[len])            {                len++;                lps[i] = len;                i++;            }            else // (pat[i] != pat[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 str is repetition of    // one of its substrings else return false.    function isRepeat(str)    {                   // Find length of string and create        // an array to store lps values used        // in KMP        let n = str.length;        let lps = new Array(n);        lps.fill(0);               // Preprocess the pattern (calculate        // lps[] array)        computeLPSArray(str, n, lps);               // Find length of longest suffix        // which is also prefix of str.        let len = lps[n-1];           // If there exist a suffix which is also        // prefix AND Length of the remaining        // substring divides total length, then        // str[0..n-len-1] is the substring that        // repeats n/(n-len) times (Readers can        // print substring and value of n/(n-len)        // for more clarity.        return (len > 0 && n % (n - len) == 0)                               ? true : false;    }         let txt = ["ABCABC", "ABABAB",                    "ABCDABCD", "GEEKSFORGEEKS",                       "GEEKGEEK", "AAAACAAAAC",                                     "ABCDABC"];    let n = txt.length;     for (let i = 0; i < n; i++)    {      if(isRepeat(txt[i]) == true)        document.write("True" + "</br>");      else        document.write("False" + "</br>");    } </script>
Output: 
True
True
True
False
True
True
False 
Time Complexity: Time complexity of the above solution is O(n) as it uses KMP preprocessing algorithm which is linear time algorithm.
This article is contributed by Harshit Agrawal. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Another approach:
Above problem can be solved with out using KMP algorithm and extra space.
This approach uses two pointers to check the minimum period of a String as a first step. Period of a String is the length of prefix substring which can be repeated x(x=length/period) times to construct the given string. 
for eg: Input string “abcabcabcabc” is having a period 3. which means we can construct the given string by repeating first 3 characters  4 (length/3=4) number of times.
Approach:
1) Initially set first pointer – i at 0th index of given string and second pointer – j at 1st index.
2) check the characters at both index. if both matches, take period as (j-i) and increment i and j.
3) if doesn’t match, Once again check if current character matches with first character at 0th index. if matches, update period as j(j-0=j) and set i to next character.
4)if both characters not matches, set i to 0 and update period to -1.
5) At the end check if the calculated period exactly divides the length of the string. if not, update period to -1. This check eliminates the presence of strings ending with suffix less than the period. for e.g period for the string “GEEKSFORGEEKS” is calculated as 8 but the suffix string(GEEKS) is having 5 characters only and is incomplete.
 
C++
Java
Python3
Javascript
/*package whatever //do not write package name here */#include <bits/stdc++.h>using namespace std; int findPeriod(string A){    int length = A.size();     // Initially consider there is no period for given    // String    int period = -1;     /*set two pointers one(i) at    index 0 and other(j) at index 1. increment j till    first character is obtained in the string*/    int i = 0;    for (int j = 1; j < length; j++) {        int currChar = A[j];        int comparator = A[i];         /*If current character matches with first         *character         *update period as the difference of j and i*/        if (currChar == comparator) {            period = (j - i);            i++;        }         /* if any mismatch occurs in between set i to         * zero also check if current character again         * matches         * with starting character. If matches, update         * period*/        else {            if (currChar == A[0]) {                i = 1;                period = j;            }            else {                i = 0;                period = -1;            }        }    }     /*check if the period is exactly dividing     * string if not reset the period to -1     * this eliminates partial substrings like     * e.g string -"GEEKSFORGEEKS" */     period = (length % period != 0) ? -1 : period;    return period;}int main(){    vector<string> testStrings        = { "ABCABC",        "ABABAB",   "ABCDABCD",            "GEEKSFORGEEKS", "GEEKGEEK", "AAAACAAAAC",            "ABCDABC" };    int n = testStrings.size();    for (int i = 0; i < n; i++) {        if (findPeriod(testStrings[i]) == -1)            cout << "false\n";        else            cout << "True\n";    }     return 0;}     // This code is contributed by rakeshsahni
/*package whatever //do not write package name here */import java.io.*; class GFG {    public static int findPeriod(String A)    {        int length = A.length();         // Initially consider there is no period for given        // String        int period = -1;         /*set two pointers one(i) at        index 0 and other(j) at index 1. increment j till        first character is obtained  in the string*/        int i = 0;        for (int j = 1; j < length; j++) {            int currChar = A.charAt(j);            int comparator = A.charAt(i);             /*If current character matches with first             *character             *update period as the difference of j and i*/            if (currChar == comparator) {                period = (j - i);                i++;            }             /* if any mismatch occurs in between set i to             * zero also check if current character again             * matches             * with starting character. If matches, update             * period*/            else {                if (currChar == A.charAt(0)) {                    i = 1;                    period = j;                }                else {                    i = 0;                    period = -1;                }            }        }         /*check if the period is exactly dividing         * string if not reset the period to -1         * this eliminates partial substrings like         *  e.g string -"GEEKSFORGEEKS"  */         period = (length % period != 0) ? -1 : period;        return period;    }    public static void main(String[] args)    {        String[] testStrings            = { "ABCABC",        "ABABAB",   "ABCDABCD",                "GEEKSFORGEEKS", "GEEKGEEK", "AAAACAAAAC",                "ABCDABC" };        int n = testStrings.length;        for (int i = 0; i < n; i++) {            if (findPeriod(testStrings[i]) == -1)                System.out.println("false");            else                System.out.println("True");        }    }}
def findPeriod(A):     length = len(A)     # Initially consider there is no period for given    # String    period = -1     # set two pointers one(i) at    # index 0 and other(j) at index 1. increment j till    # first character is obtained in the string    i = 0    for j in range(1,length):        currChar = A[j]        comparator = A[i]         # If current character matches with first        # character        # update period as the difference of j and i        if (currChar == comparator):            period = (j - i)            i += 1         #  if any mismatch occurs in between set i to        #  zero also check if current character again        #  matches        #  with starting character. If matches, update        #  period        else:            if (currChar == A[0]):                i = 1                period = j            else:                i = 0                period = -1     #  check if the period is exactly dividing    #  string if not reset the period to -1    #  this eliminates partial substrings like    #  e.g string -"GEEKSFORGEEKS"     period = -1 if (length % period != 0) else period    return period testStrings = [ "ABCABC",     "ABABAB", "ABCDABCD", "GEEKSFORGEEKS", "GEEKGEEK", "AAAACAAAAC", "ABCDABC" ]n = len(testStrings)for i in range(n):    if (findPeriod(testStrings[i]) == -1):        print("false")    else:        print("True") # This code is contributed by shinjanpatra
<script> function findPeriod(A){    let length = A.length;     // Initially consider there is no period for given    // String    let period = -1;     /*set two pointers one(i) at    index 0 and other(j) at index 1. increment j till    first character is obtained in the string*/    let i = 0;    for (let j = 1; j < length; j++) {        let currChar = A[j];        let comparator = A[i];         /*If current character matches with first        *character        *update period as the difference of j and i*/        if (currChar == comparator) {            period = (j - i);            i++;        }         /* if any mismatch occurs in between set i to        * zero also check if current character again        * matches        * with starting character. If matches, update        * period*/        else {            if (currChar == A[0]) {                i = 1;                period = j;            }            else {                i = 0;                period = -1;            }        }    }     /*check if the period is exactly dividing    * string if not reset the period to -1    * this eliminates partial substrings like    * e.g string -"GEEKSFORGEEKS" */     period = (length % period != 0) ? -1 : period;    return period;}// driver code let testStrings    = [ "ABCABC",     "ABABAB", "ABCDABCD","GEEKSFORGEEKS", "GEEKGEEK", "AAAACAAAAC","ABCDABC" ];let n = testStrings.length;for (let i = 0; i < n; i++) {    if (findPeriod(testStrings[i]) == -1)        document.write("false","</br>");    else        document.write("True","</br>");}  // This code is contributed by shinjanpatra </script>
True
True
True
false
True
True
false
This approach is contributed by Sai Krishna Sribhshyam, please do comment if any thing is incorrect or if you want to share any further info.
Sam007
vaibhavrabadiya117
sumitkumar27022001
sagartomar9927
kashishsoda
amartyaghoshgfg
germanshephered48
saikrishnasribhshyam
rakeshsahni
shinjanpatra
adityakumar129
Amazon
MakeMyTrip
Strings
Amazon
MakeMyTrip
Strings
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Python program to check if a string is palindrome or not
Array of Strings in C++ (5 Different Ways to Create)
Convert string to char array in C++
Longest Palindromic Substring | Set 1
Caesar Cipher in Cryptography
Check whether two strings are anagram of each other
Top 50 String Coding Problems for Interviews
Length of the longest substring without repeating characters
Reverse words in a given string
How to split a string in C/C++, Python and Java?