Minimum rotations required to get the same String | Set-2 - GeeksforGeeks

15 Jun, 2021
Given a string, we need to find the minimum number of rotations required to get the same string. In this case, we will only consider Left rotations.
Examples: 
Input : s = “geeks” Output : 5
Input : s = “aaaa” Output :1 
Naive approach: The basic approach is to keep rotating the string from the first position and count the number of rotations until we get the initial string.
Efficient Approach : We will follow the basic approach but will try to reduce the time taken in generating rotations.The idea is as follows:  
Generate a new string of double size of the input string as:
newString = original string excluding first character 
            + original string with the first character.

+ denotes concatenation here.  
If original string is str = “abcd”, new string will be “bcdabcd”.
Now, the task remains to search for the original string in the newly generated string and the index where the string is found in the number of rotations required.
For string matching, we will use KMP algorithm which performs string matching in linear time.
Below is the implementation of the above approach:  
C++
Java
Python3
C#
Javascript
// C++ implementation of the above approach#include <bits/stdc++.h>using namespace std;void computeLPSArray(char* pat, int M, int* lps);  // Prints occurrences of txt[] in pat[]int KMPSearch(char* pat, char* txt){    int M = strlen(pat);    int N = strlen(txt);      // Create lps[] that will hold the longest    // prefix suffix values for pattern    int lps[M];      // Preprocess the pattern (calculate lps[] array)    computeLPSArray(pat, M, lps);      // Index for txt[] , // index for pat[]    int i = 0;    int j = 0;    while (i < N) {        if (pat[j] == txt[i]) {            j++;            i++;        }          if (j == M) {            return i - j;            j = lps[j - 1];        }          // Mismatch after j matches        else if (i < N && pat[j] != txt[i]) {             // Do not match lps[0..lps[j-1]] characters,            // they will match anyway            if (j != 0)                j = lps[j - 1];            else                i = i + 1;        }    }}  // Fills lps[] for given pattern pat[0..M-1]void computeLPSArray(char* pat, int M, int* lps){    // Length of the previous longest prefix suffix    int len = 0;         // lps[0] is always 0    lps[0] = 0;      // The loop calculates lps[i] for i = 1 to M-1    int i = 1;    while (i < M) {        if (pat[i] == pat[len]) {            len++;            lps[i] = len;            i++;        }         // (pat[i] != pat[len])        else        {            // This is tricky. Consider the example.            // AAACAAAA and i = 7. The idea is similar            // to search step.            if (len != 0) {                len = lps[len - 1];            }            else            {                lps[i] = 0;                i++;            }        }    }} // Returns count of rotations to get the// same string backint countRotations(string s){    // Form a string excluding the first character    // and concatenating the string at the end    string s1 = s.substr(1, s.size() - 1) + s;      // Convert the string to character array    char pat[s.length()], text[s1.length()];      strcpy(pat, s.c_str());    strcpy(text, s1.c_str());      // Use the KMP search algorithm    // to find it in O(N) time    return 1 + KMPSearch(pat, text);}  // Driver codeint main(){    string s1 = "geeks";      cout << countRotations(s1);      return 0;}
// Java implementation of the above approachclass GFG{ // Prints occurrences of txt[] in pat[]static int KMPSearch(char []pat, char []txt){    int M = pat.length;    int N = txt.length;      // Create lps[] that will hold the longest    // prefix suffix values for pattern    int lps[] = new int[M];      // Preprocess the pattern (calculate lps[] array)    computeLPSArray(pat, M, lps);      // Index for txt[] , // index for pat[]    int i = 0;    int j = 0;    while (i < N)    {        if (pat[j] == txt[i])        {            j++;            i++;        }          if (j == M)        {            return i - j + 1;            //j = lps[j - 1];        }          // Mismatch after j matches        else if (i < N && pat[j] != txt[i])        {             // Do not match lps[0..lps[j-1]] characters,            // they will match anyway            if (j != 0)                j = lps[j - 1];            else                i = i + 1;        }    }    return 0;}  // Fills lps[] for given pattern pat[0..M-1]static void computeLPSArray(char []pat, int M, int []lps){       // Length of the previous longest prefix suffix    int len = 0;         // lps[0] is always 0    lps[0] = 0;      // The loop calculates lps[i] for i = 1 to M-1    int i = 1;    while (i < M)    {        if (pat[i] == pat[len])        {            len++;            lps[i] = len;            i++;        }         // (pat[i] != pat[len])        else        {            // This is tricky. Consider the example.            // AAACAAAA and i = 7. The idea is similar            // to search step.            if (len != 0) {                len = lps[len - 1];            }            else            {                lps[i] = 0;                i++;            }        }    }} // Returns count of rotations to get the// same String backstatic int countRotations(String s){    // Form a String excluding the first character    // and concatenating the String at the end    String s1 = s.substring(1, s.length() - 1) + s;      // Convert the String to character array    char []pat = s.toCharArray();    char []text = s1.toCharArray();      // Use the KMP search algorithm    // to find it in O(N) time    return 1 + KMPSearch(pat, text);}  // Driver codepublic static void main(String []args){    String s1 = "geeks";    System.out.print(countRotations(s1));}} // This code is contributed by rutvik_56.
# Python3 implementation of the above approach # Prints occurrences of txt[] in pat[]def KMPSearch(pat, txt):     M = len(pat)    N = len(txt)     # Create lps[] that will hold the longest    # prefix suffix values for pattern    lps = [0] * M     # Preprocess the pattern (calculate lps[] array)    computeLPSArray(pat, M, lps)     # Index for txt[] , # index for pat[]    i = 0    j = 0    while i < N:        if pat[j] == txt[i]:            j += 1            i += 1         if j == M:            return i - j            j = lps[j - 1]         # Mismatch after j matches        elif i < N and pat[j] != txt[i]:             # Do not match lps[0..lps[j-1]] characters,            # they will match anyway            if j != 0:                j = lps[j - 1]            else:                i = i + 1 # Fills lps[] for given pattern pat[0..M-1]def computeLPSArray(pat, M, lps):         # Length of the previous longest prefix suffix    _len = 0         # lps[0] is always 0    lps[0] = 0     # The loop calculates lps[i] for i = 1 to M-1    i = 1    while i < M:        if pat[i] == pat[_len]:            _len += 1            lps[i] = _len            i += 1         # (pat[i] != pat[_len])        else:                     # This is tricky. Consider the example.            # AAACAAAA and i = 7. The idea is similar            # to search step.            if _len != 0:                _len = lps[_len - 1]            else:                lps[i] = 0                i += 1 # Returns count of rotations to get the# same string backdef countRotations(s):     # Form a string excluding the first character    # and concatenating the string at the end    s1 = s[1 : len(s)] + s     # Convert the string to character array    pat = s[:]    text = s1[:]     # Use the KMP search algorithm    # to find it in O(N) time    return 1 + KMPSearch(pat, text) # Driver codes1 = "geeks"print(countRotations(s1)) # This code is contributed by divyamohan123
// C# implementation of the above approachusing System; class GFG{ // Prints occurrences of txt[] in pat[]static int KMPSearch(char []pat, char []txt){    int M = pat.Length;    int N = txt.Length;      // Create lps[] that will hold the longest    // prefix suffix values for pattern    int []lps = new int[M];      // Preprocess the pattern (calculate lps[] array)    computeLPSArray(pat, M, lps);      // Index for txt[] , // index for pat[]    int i = 0;    int j = 0;         while (i < N)    {        if (pat[j] == txt[i])        {            j++;            i++;        }          if (j == M)        {            return i - j ;            //j = lps[j - 1];        }          // Mismatch after j matches        else if (i < N && pat[j] != txt[i])        {                         // Do not match lps[0..lps[j-1]]            // characters, they will match anyway            if (j != 0)                j = lps[j - 1];            else                i = i + 1;        }    }    return 0;}  // Fills lps[] for given pattern pat[0..M-1]static void computeLPSArray(char []pat, int M,                            int []lps){         // Length of the previous longest    // prefix suffix    int len = 0;         // lps[0] is always 0    lps[0] = 0;      // The loop calculates lps[i]    // for i = 1 to M-1    int i = 1;         while (i < M)    {        if (pat[i] == pat[len])        {            len++;            lps[i] = len;            i++;        }         // (pat[i] != pat[len])        else        {                         // This is tricky. Consider the example.            // AAACAAAA and i = 7. The idea is similar            // to search step.            if (len != 0) {                len = lps[len - 1];            }            else            {                lps[i] = 0;                i++;            }        }    }} // Returns count of rotations to get the// same string backstatic int countRotations(string s){         // Form a string excluding the first character    // and concatenating the string at the end    string s1 = s.Substring(1, s.Length - 1) + s;      // Convert the string to character array    char []pat = s.ToCharArray();    char []text = s1.ToCharArray();      // Use the KMP search algorithm    // to find it in O(N) time    return 1 + KMPSearch(pat, text);}  // Driver codepublic static void Main(params string []args){    string s1 = "geeks";         Console.Write(countRotations(s1));}} // This code is contributed by pratham76
<script>     // JavaScript implementation of the above approach         // Prints occurrences of txt[] in pat[]    function KMPSearch(pat, txt)    {        let M = pat.length;        let N = txt.length;         // Create lps[] that will hold the longest        // prefix suffix values for pattern        let lps = new Array(M);        lps.fill(0);         // Preprocess the pattern (calculate lps[] array)        computeLPSArray(pat, M, lps);         // Index for txt[] , // index for pat[]        let i = 0;        let j = 0;         while (i < N)        {            if (pat[j] == txt[i])            {                j++;                i++;            }             if (j == M)            {                return i - j ;                //j = lps[j - 1];            }             // Mismatch after j matches            else if (i < N && pat[j] != txt[i])            {                 // Do not match lps[0..lps[j-1]]                // characters, they will match anyway                if (j != 0)                    j = lps[j - 1];                else                    i = i + 1;            }        }        return 0;    }     // Fills lps[] for given pattern pat[0..M-1]    function computeLPSArray(pat, M, lps)    {         // Length of the previous longest        // prefix suffix        let len = 0;         // lps[0] is always 0        lps[0] = 0;         // The loop calculates lps[i]        // for i = 1 to M-1        let i = 1;         while (i < M)        {            if (pat[i] == pat[len])            {                len++;                lps[i] = len;                i++;            }             // (pat[i] != pat[len])            else            {                 // This is tricky. Consider the example.                // AAACAAAA and i = 7. The idea is similar                // to search step.                if (len != 0) {                    len = lps[len - 1];                }                else                {                    lps[i] = 0;                    i++;                }            }        }    }     // Returns count of rotations to get the    // same string back    function countRotations(s)    {         // Form a string excluding the first character        // and concatenating the string at the end        let s1 = s.substring(1, s.length) + s;         // Convert the string to character array        let pat = s.split('');        let text = s1.split('');         // Use the KMP search algorithm        // to find it in O(N) time        return 1 + KMPSearch(pat, text);    }         let s1 = "geeks";          document.write(countRotations(s1)); </script>
5
 
Time Complexity : O(N). 
divyamohan123
rutvik_56
pratham76
simranarora5sos
divyeshrabadiya07
Pattern Searching
Strings
Strings
Pattern Searching
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
How to validate HTML tag using Regular Expression
Build a DFA to accept Binary strings that starts or ends with "01"
How to validate pin code of India using Regular Expression
How to check Aadhaar number is valid or not using Regular Expression
How to validate time in 24-hour format using Regular Expression
Reverse a string in Java
Longest Common Subsequence | DP-4
Write a program to reverse an array or string
Write a program to print all permutations of a given string
C++ Data Types