Check if a given string is a rotation of a palindrome

Given a string, check if it is a rotation of a palindrome. For example your function should return true for “aab” as it is a rotation of “aba”.

Examples:

Input:  str = "aaaad"
Output: 1  
// "aaaad" is a rotation of a palindrome "aadaa"

Input:  str = "abcd"
Output: 0
// "abcd" is not a rotation of any palindrome.



We strongly recommend that you click here and practice it, before moving on to the solution.


A Simple Solution is to take the input string, try every possible rotation of it and return true if a rotation is a palindrome. If no rotation is palindrome, then return false.
Following is the implementation of this approach.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <iostream>
#include <string>
using namespace std;
  
// A utility function to check if a string str is palindrome
bool isPalindrome(string str)
{
    // Start from leftmost and rightmost corners of str
    int l = 0;
    int h = str.length() - 1;
  
    // Keep comparing characters while they are same
    while (h > l)
        if (str[l++] != str[h--])
            return false;
  
    // If we reach here, then all characters were matching
    return true;
}
  
// Function to check if a given string is a rotation of a
// palindrome.
bool isRotationOfPalindrome(string str)
{
    // If string iteself is palindrome
    if (isPalindrome(str))
        return true;
  
    // Now try all rotations one by one
    int n = str.length();
    for (int i = 0; i < n - 1; i++) {
        string str1 = str.substr(i + 1, n - i - 1);
        string str2 = str.substr(0, i + 1);
  
        // Check if this rotation is palindrome
        if (isPalindrome(str1.append(str2)))
            return true;
    }
    return false;
}
  
// Driver program to test above function
int main()
{
    cout << isRotationOfPalindrome("aab") << endl;
    cout << isRotationOfPalindrome("abcde") << endl;
    cout << isRotationOfPalindrome("aaaad") << endl;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to check if a given string
// is a rotation of a palindrome
import java.io.*;
  
class Palindrome {
    // A utility function to check if a string str is palindrome
    static boolean isPalindrome(String str)
    {
        // Start from leftmost and rightmost corners of str
        int l = 0;
        int h = str.length() - 1;
  
        // Keep comparing characters while they are same
        while (h > l)
            if (str.charAt(l++) != str.charAt(h--))
                return false;
  
        // If we reach here, then all characters were matching
        return true;
    }
  
    // Function to check if a given string is a rotation of a
    // palindrome
    static boolean isRotationOfPalindrome(String str)
    {
        // If string iteself is palindrome
        if (isPalindrome(str))
            return true;
  
        // Now try all rotations one by one
        int n = str.length();
        for (int i = 0; i < n - 1; i++) {
            String str1 = str.substring(i + 1);
            String str2 = str.substring(0, i + 1);
  
            // Check if this rotation is palindrome
            if (isPalindrome(str1 + str2))
                return true;
        }
        return false;
    }
  
    // driver program
    public static void main(String[] args)
    {
        System.out.println((isRotationOfPalindrome("aab")) ? 1 : 0);
        System.out.println((isRotationOfPalindrome("abcde")) ? 1 : 0);
        System.out.println((isRotationOfPalindrome("aaaad")) ? 1 : 0);
    }
}
  
// Contributed by Pramod Kumar

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to check if a given string is a rotation
# of a palindrome
  
# A utility function to check if a string str is palindrome
def isPalindrome(string):
  
    # Start from leftmost and rightmost corners of str
    l = 0
    h = len(string) - 1
  
    # Keep comparing characters while they are same
    while h > l:
        l+= 1
        h-= 1
        if string[l-1] != string[h + 1]:
            return False
  
    # If we reach here, then all characters were matching    
    return True
  
# Function to check if a given string is a rotation of a
# palindrome.
def isRotationOfPalindrome(string):
  
    # If string itself is palindrome
    if isPalindrome(string):
        return True
  
    # Now try all rotations one by one
    n = len(string)
    for i in xrange(n-1):
        string1 = string[i + 1:n]
        string2 = string[0:i + 1]
  
        # Check if this rotation is palindrome
        string1+=(string2)
        if isPalindrome(string1):
            return True
  
    return False
  
# Driver program
print "1" if isRotationOfPalindrome("aab") == True else "0"
print "1" if isRotationOfPalindrome("abcde") == True else "0"
print "1" if isRotationOfPalindrome("aaaad") == True else "0"
  
# This code is contributed by BHAVYA JAIN

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to check if a given string
// is a rotation of a palindrome
using System;
  
class GFG {
    // A utility function to check if
    // a string str is palindrome
    public static bool isPalindrome(string str)
    {
        // Start from leftmost and
        // rightmost corners of str
        int l = 0;
        int h = str.Length - 1;
  
        // Keep comparing characters
        // while they are same
        while (h > l) {
            if (str[l++] != str[h--]) {
                return false;
            }
        }
  
        // If we reach here, then all
        // characters were matching
        return true;
    }
  
    // Function to check if a given string
    // is a rotation of a palindrome
    public static bool isRotationOfPalindrome(string str)
    {
        // If string iteself is palindrome
        if (isPalindrome(str)) {
            return true;
        }
  
        // Now try all rotations one by one
        int n = str.Length;
        for (int i = 0; i < n - 1; i++) {
            string str1 = str.Substring(i + 1);
            string str2 = str.Substring(0, i + 1);
  
            // Check if this rotation is palindrome
            if (isPalindrome(str1 + str2)) {
                return true;
            }
        }
        return false;
    }
  
    // Driver Code
    public static void Main(string[] args)
    {
        Console.WriteLine((isRotationOfPalindrome("aab")) ? 1 : 0);
        Console.WriteLine((isRotationOfPalindrome("abcde")) ? 1 : 0);
        Console.WriteLine((isRotationOfPalindrome("aaaad")) ? 1 : 0);
    }
}
  
// This code is contributed by Shrikant13

chevron_right



Output:

1
0
1

Time Complexity: O(n2)
Auxiliary Space: O(n) for storing rotations.
Note that the above algorithm can be optimized to work in O(1) extra space as we can rotate a string in O(n) time and O(1) extra space.

An Optimized Solution can work in O(n) time. The idea here is to use Manacher’s algorithm to solve the above problem.

  • Let the given string be ‘s’ and length of string be ‘n’.
  • Preprocess/Prepare the string to use Manachers Algorithm, to help find even length palindrome, for which we concatenate the given string with itself (to find if rotation will give a palindrome) and add ‘$’ symbol at the beginning and ‘#’ characters between letters. We end the string using ‘@’. So for ‘aaad’ input the reformed string will be – ‘$#a#a#a#a#d#a#a#a#a#d#@’
  • Now the problem reduces to finding Longest Palindromic Substring using Manacher’s algorithm of length n or greater in the string.
  • If there is palindromic substring of length n, then return true, else return false. If we find a palindrome of greater length then we check if the size of our input is even or odd, correspondingly our palindrome length found should also be even or odd.

For eg. if our input size is 3 and while performing Manacher’s Algorithm we get a palindrome size of 5 it obviously would contain a substring of size of 3 which is a palindrome but the same cannot be said for a palindrome of length of 4. Hence we check if both the size of the input and the size of palindrome found at any instance is both even or both odd.

Boundary case would be a word with same letters that would defy the above property but for that case our algorithm will find both even length and odd length palindrome one of them being a substring, hence it wont be a problem.

Below is the implementation of the above algorithm:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to check if we have found
// a palindrome of same length as the input
// which is a rotation of the input string
bool checkPal(int x, int len)
{
    if (x == len)
        return true;
    else if (x > len) {
        if ((x % 2 == 0 && len % 2 == 0)
            || (x % 2 != 0 && len % 2 != 0))
            return true;
    }
    return false;
}
  
// Function to preprocess the string
// for Manacher's Algorithm
string reform(string s)
{
    string s1 = "$#";
  
    // Adding # between the characters
    for (int i = 0; i < s.size(); i++) {
        s1 += s[i];
        s1 += '#';
    }
  
    s1 += '@';
    return s1;
}
  
// Function to find the longest palindromic
// substring using Manacher's Algorithm
bool longestPal(string s, int len)
{
  
    // Current Left Position
    int mirror = 0;
  
    // Center Right Position
    int R = 0;
  
    // Center Position
    int C = 0;
  
    // LPS Length Array
    int P[s.size()] = { 0 };
    int x = 0;
  
    // Get currentLeftPosition Mirror
    // for currentRightPosition i
    for (int i = 1; i < s.size() - 1; i++) {
        mirror = 2 * C - i;
  
        // If currentRightPosition i is
        // within centerRightPosition R
        if (i < R)
            P[i] = min((R - i), P[mirror]);
  
        // Attempt to expand palindrome centered
        // at currentRightPosition i
        while (s[i + (1 + P[i])] == s[i - (1 + P[i])]) {
            P[i]++;
        }
  
        // Check for palindrome
        bool ans = checkPal(P[i], len);
        if (ans)
            return true;
  
        // If palindrome centered at currentRightPosition i
        // expand beyond centerRightPosition R,
        // adjust centerPosition C based on expanded palindrome
        if (i + P[i] > R) {
            C = i;
            R = i + P[i];
        }
    }
  
    return false;
}
  
// Driver code
int main()
{
    string s = "aaaad";
    int len = s.size();
    s += s;
    s = reform(s);
    cout << longestPal(s, len);
  
    return 0;
}
  
// This code is contributed by Vindusha Pankajakshan

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach 
import java.util.*;
  
class GFG 
{
  
// Function to check if we have found 
// a palindrome of same length as the input 
// which is a rotation of the input string 
static boolean checkPal(int x, int len) 
{
    if (x == len)
    {
        return true;
    
    else if (x > len) 
    {
        if ((x % 2 == 0 && len % 2 == 0) ||
            (x % 2 != 0 && len % 2 != 0)) 
        {
            return true;
        }
    }
    return false;
}
  
// Function to preprocess the string 
// for Manacher's Algorithm 
static String reform(String s)
{
    String s1 = "$#";
  
    // Adding # between the characters 
    for (int i = 0; i < s.length(); i++) 
    {
        s1 += s.charAt(i);
        s1 += '#';
    }
  
    s1 += '@';
    return s1;
}
  
// Function to find the longest palindromic 
// substring using Manacher's Algorithm 
static boolean longestPal(String s, int len) 
{
  
    // Current Left Position 
    int mirror = 0;
  
    // Center Right Position 
    int R = 0;
  
    // Center Position 
    int C = 0;
  
    // LPS Length Array 
    int[] P = new int[s.length()];
    int x = 0;
  
    // Get currentLeftPosition Mirror 
    // for currentRightPosition i 
    for (int i = 1; i < s.length() - 1; i++)
    {
        mirror = 2 * C - i;
  
        // If currentRightPosition i is 
        // within centerRightPosition R 
        if (i < R) 
        {
            P[i] = Math.min((R - i), P[mirror]);
        }
  
        // Attempt to expand palindrome centered 
        // at currentRightPosition i 
        while (s.charAt(i + (1 + P[i])) == 
               s.charAt(i - (1 + P[i])))
        {
            P[i]++;
        }
  
        // Check for palindrome 
        boolean ans = checkPal(P[i], len);
        if (ans) 
        {
            return true;
        }
  
        // If palindrome centered at currentRightPosition i 
        // expand beyond centerRightPosition R, 
        // adjust centerPosition C based on expanded palindrome 
        if (i + P[i] > R) 
        {
            C = i;
            R = i + P[i];
        }
    }
    return false;
}
  
// Driver code 
public static void main(String[] args) 
{
    String s = "aaaad";
    int len = s.length();
    s += s;
    s = reform(s);
    System.out.println(longestPal(s, len) ? 1 : 0);
}
  
// This code is contributed by PrinciRaj1992

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach 
using System;
using System.Collections.Generic; 
  
class GFG 
{
  
// Function to check if we have found 
// a palindrome of same length as the input 
// which is a rotation of the input string 
static bool checkPal(int x, int len) 
{
    if (x == len)
    {
        return true;
    
    else if (x > len) 
    {
        if ((x % 2 == 0 && len % 2 == 0) ||
            (x % 2 != 0 && len % 2 != 0)) 
        {
            return true;
        }
    }
    return false;
}
  
// Function to preprocess the string 
// for Manacher's Algorithm 
static String reform(String s)
{
    String s1 = "$#";
  
    // Adding # between the characters 
    for (int i = 0; i < s.Length; i++) 
    {
        s1 += s[i];
        s1 += '#';
    }
  
    s1 += '@';
    return s1;
}
  
// Function to find the longest palindromic 
// substring using Manacher's Algorithm 
static bool longestPal(String s, int len) 
{
  
    // Current Left Position 
    int mirror = 0;
  
    // Center Right Position 
    int R = 0;
  
    // Center Position 
    int C = 0;
  
    // LPS Length Array 
    int[] P = new int[s.Length];
    int x = 0;
  
    // Get currentLeftPosition Mirror 
    // for currentRightPosition i 
    for (int i = 1; i < s.Length - 1; i++)
    {
        mirror = 2 * C - i;
  
        // If currentRightPosition i is 
        // within centerRightPosition R 
        if (i < R) 
        {
            P[i] = Math.Min((R - i), P[mirror]);
        }
  
        // Attempt to expand palindrome centered 
        // at currentRightPosition i 
        while (s[i + (1 + P[i])] == s[i - (1 + P[i])])
        {
            P[i]++;
        }
  
        // Check for palindrome 
        bool ans = checkPal(P[i], len);
        if (ans) 
        {
            return true;
        }
  
        // If palindrome centered at currentRightPosition i 
        // expand beyond centerRightPosition R, 
        // adjust centerPosition C based on expanded palindrome 
        if (i + P[i] > R) 
        {
            C = i;
            R = i + P[i];
        }
    }
    return false;
}
  
// Driver code 
public static void Main(String[] args) 
{
    String s = "aaaad";
    int len = s.Length;
    s += s;
    s = reform(s);
    Console.WriteLine(longestPal(s, len) ? 1 : 0);
}
  
// This code is contributed by Rajput-Ji

chevron_right


Output:

1

This article is contributed Abhay Rathi. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up



Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.