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.
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.
Implementation:
C++
#include <iostream>
#include <string>
using namespace std;
bool isPalindrome(string str)
{
int l = 0;
int h = str.length() - 1;
while (h > l)
if (str[l++] != str[h--])
return false ;
return true ;
}
bool isRotationOfPalindrome(string str)
{
if (isPalindrome(str))
return true ;
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);
if (isPalindrome(str1.append(str2)))
return true ;
}
return false ;
}
int main()
{
cout << isRotationOfPalindrome( "aab" ) << endl;
cout << isRotationOfPalindrome( "abcde" ) << endl;
cout << isRotationOfPalindrome( "aaaad" ) << endl;
return 0;
}
|
Java
import java.io.*;
class Palindrome {
static boolean isPalindrome(String str)
{
int l = 0 ;
int h = str.length() - 1 ;
while (h > l)
if (str.charAt(l++) != str.charAt(h--))
return false ;
return true ;
}
static boolean isRotationOfPalindrome(String str)
{
if (isPalindrome(str))
return true ;
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 );
if (isPalindrome(str1 + str2))
return true ;
}
return false ;
}
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 );
}
}
|
Python3
def isPalindrome(string):
l = 0
h = len (string) - 1
while h > l:
l + = 1
h - = 1
if string[l - 1 ] ! = string[h + 1 ]:
return False
return True
def isRotationOfPalindrome(string):
if isPalindrome(string):
return True
n = len (string)
for i in range (n - 1 ):
string1 = string[i + 1 :n]
string2 = string[ 0 :i + 1 ]
string1 + = (string2)
if isPalindrome(string1):
return True
return False
print ( "1" if isRotationOfPalindrome( "aab" ) = = True else "0" )
print ( "1" if isRotationOfPalindrome( "abcde" ) = = True else "0" )
print ( "1" if isRotationOfPalindrome( "aaaad" ) = = True else "0" )
|
C#
using System;
class GFG {
public static bool isPalindrome( string str)
{
int l = 0;
int h = str.Length - 1;
while (h > l) {
if (str[l++] != str[h--]) {
return false ;
}
}
return true ;
}
public static bool isRotationOfPalindrome( string str)
{
if (isPalindrome(str)) {
return true ;
}
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);
if (isPalindrome(str1 + str2)) {
return true ;
}
}
return false ;
}
public static void Main( string [] args)
{
Console.WriteLine((isRotationOfPalindrome( "aab" )) ? 1 : 0);
Console.WriteLine((isRotationOfPalindrome( "abcde" )) ? 1 : 0);
Console.WriteLine((isRotationOfPalindrome( "aaaad" )) ? 1 : 0);
}
}
|
Javascript
<script>
function isPalindrome( str)
{
var l = 0;
var h = str.length - 1;
while (h > l) {
if (str[l++] != str[h--]) {
return false ;
}
}
return true ;
}
function isRotationOfPalindrome( str)
{
if (isPalindrome(str)) {
return true ;
}
var n = str.length;
for ( var i = 0; i < n - 1; i++) {
var str1 = str.substring(i + 1);
var str2 = str.substring(0, i + 1);
if (isPalindrome(str1 + str2)) {
return true ;
}
}
return false ;
}
document.write((isRotationOfPalindrome( "aab" )) ? 1 : 0 );
document.write( "<br>" );
document.write((isRotationOfPalindrome( "abcde" )) ? 1 : 0 );
document.write( "<br>" );
document.write((isRotationOfPalindrome( "aaaad" )) ? 1 : 0);
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
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 ;
}
string reform(string s)
{
string s1 = "$#" ;
for ( int i = 0; i < s.size(); i++) {
s1 += s[i];
s1 += '#' ;
}
s1 += '@' ;
return s1;
}
bool longestPal(string s, int len)
{
int mirror = 0;
int R = 0;
int C = 0;
int P[s.size()] = { 0 };
int x = 0;
for ( int i = 1; i < s.size() - 1; i++) {
mirror = 2 * C - i;
if (i < R)
P[i] = min((R - i), P[mirror]);
while (s[i + (1 + P[i])] == s[i - (1 + P[i])]) {
P[i]++;
}
bool ans = checkPal(P[i], len);
if (ans)
return true ;
if (i + P[i] > R) {
C = i;
R = i + P[i];
}
}
return false ;
}
int main()
{
string s = "aaaad" ;
int len = s.size();
s += s;
s = reform(s);
cout << longestPal(s, len);
return 0;
}
|
Java
import java.util.*;
class GFG
{
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 ;
}
static String reform(String s)
{
String s1 = "$#" ;
for ( int i = 0 ; i < s.length(); i++)
{
s1 += s.charAt(i);
s1 += '#' ;
}
s1 += '@' ;
return s1;
}
static boolean longestPal(String s, int len)
{
int mirror = 0 ;
int R = 0 ;
int C = 0 ;
int [] P = new int [s.length()];
int x = 0 ;
for ( int i = 1 ; i < s.length() - 1 ; i++)
{
mirror = 2 * C - i;
if (i < R)
{
P[i] = Math.min((R - i), P[mirror]);
}
while (s.charAt(i + ( 1 + P[i])) ==
s.charAt(i - ( 1 + P[i])))
{
P[i]++;
}
boolean ans = checkPal(P[i], len);
if (ans)
{
return true ;
}
if (i + P[i] > R)
{
C = i;
R = i + P[i];
}
}
return false ;
}
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 );
}
}
|
Python3
def checkPal (x, Len ):
if (x = = Len ):
return True
elif (x > Len ):
if ((x % 2 = = 0 and Len % 2 = = 0 ) or (x % 2 ! = 0 and Len % 2 ! = 0 )):
return True
return False
def reform (s):
s1 = "$#"
for i in range ( len (s)):
s1 + = s[i]
s1 + = "#"
s1 + = "@"
return s1
def longestPal (s, Len ):
mirror = 0
R = 0
C = 0
P = [ 0 ] * len (s)
x = 0
for i in range ( 1 , len (s) - 1 ):
mirror = 2 * C - i
if (i < R):
P[i] = min ((R - i), P[mirror])
while (s[i + ( 1 + P[i])] = = s[i - ( 1 + P[i])]):
P[i] + = 1
ans = checkPal(P[i], Len )
if (ans):
return True
if (i + P[i] > R):
C = i
R = i + P[i]
return False
if __name__ = = '__main__' :
s = "aaaad"
Len = len (s)
s + = s
s = reform(s)
print (longestPal(s, Len ))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
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 ;
}
static String reform(String s)
{
String s1 = "$#" ;
for ( int i = 0; i < s.Length; i++)
{
s1 += s[i];
s1 += '#' ;
}
s1 += '@' ;
return s1;
}
static bool longestPal(String s, int len)
{
int mirror = 0;
int R = 0;
int C = 0;
int [] P = new int [s.Length];
int x = 0;
for ( int i = 1; i < s.Length - 1; i++)
{
mirror = 2 * C - i;
if (i < R)
{
P[i] = Math.Min((R - i), P[mirror]);
}
while (s[i + (1 + P[i])] == s[i - (1 + P[i])])
{
P[i]++;
}
bool ans = checkPal(P[i], len);
if (ans)
{
return true ;
}
if (i + P[i] > R)
{
C = i;
R = i + P[i];
}
}
return false ;
}
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);
}
}
|
Javascript
<script>
function checkPal(x , 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 reform( s) {
var s1 = "$#" ;
for (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
function longestPal( s , len) {
var mirror = 0;
var R = 0;
var C = 0;
var P = Array(s.length).fill(0);
var x = 0;
for (i = 1; i < s.length - 1; i++) {
mirror = 2 * C - i;
if (i < R) {
P[i] = Math.min((R - i), P[mirror]);
}
while (s.charAt(i + (1 + P[i])) == s.charAt(i - (1 + P[i]))) {
P[i]++;
}
var ans = checkPal(P[i], len);
if (ans) {
return true ;
}
if (i + P[i] > R) {
C = i;
R = i + P[i];
}
}
return false ;
}
var s = "aaaad" ;
var len = s.length;
s += s;
s = reform(s);
document.write(longestPal(s, len) ? 1 : 0);
</script>
|
Time Complexity : O(n2)
Auxiliary Space: O(n)
This article is contributed by Aarti_Rathi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.