Check a string for repeated substrings
Given a string, check if it has a substring that can be used to construct the string by concatenating multiple copies of it.
For example,
Output: true
Explanation: ABC is repeated twice.
Input: str = ABCDABCDABCDABCD
Output: true
Explanation: ABCD is repeated 4 times, or ABCDABCD is repeated twice.
Input: str = ABCB
Output: false
The idea is to concatenate the input string with itself and remove the first and last characters from it. Next, search for the input string in the concatenated string; if it’s there, we can say that the string has a repeated substring. This works because the repeated substring (if it exists) would appear somewhere in the center of the string upon doubling it.
To illustrate, consider the string S, consisting of a repeated substring s, occurring n times. This can be written as follows:
S = sn
The string S when combined with itself, creates a string SS, which can be expressed as follows:
SS = sn + sn
= s2×n
= s + s(2×n-2) + s
The repeated substring s can be written as lxr, where l and r are the leftmost and rightmost characters of s, and x forms the remaining substring. When the first and last characters of the string SS are removed, we get another string SS, which can be written as follows:
SS’ = xr + s(2×n-2) + lx
Now it is evident that S exists in SS' for all n >= 2.
For n = 2, S = s2 and SS’ = xr + s2 + lx
For n = 3, S = s3 and SS’ = xr + s4 + lx
For n = 4, S = s4 and SS’ = xr + s6 + lx
For n = 5, S = s5 and SS’ = xr + s8 + lx
…
and so on.
Following is the C++, Java, and Python implementation based on the idea:
C++
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <string> using namespace std; bool check(string str) { if (str.size() == 0) { return false; } return (str + str).substr(1, 2 * str.size() - 2).find(str) != -1; } int main() { string str = "ABCDABCDABCDABCD"; cout << boolalpha << check(str); return 0; } |
Output:
true
Java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Main { public static boolean check(String str) { if (str == null || str.length() == 0) { return false; } return (str + str).substring(1, 2 * str.length() - 1).contains(str); } public static void main(String[] args) { String s = "ABCDABCDABCDABCD"; System.out.println(check(s)); } } |
Output:
true
Python
The time complexity of the above solution is O(n) where n is the length of the string.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)