Check if a given string is a rotation of a palindrome

Last Updated : 3 Aug, 2026

Given a string s, check if it can be rotated to form a palindrome. Return true if it can form a palindrome otherwise, return false.

Examples:

Input: s = "aaaab"
Output: true
Explanation: "aaaab" can be rotated 2 positions to the left (or 3 positions to the right) to obtain "aabaa", which is a palindrome.

Input: s = "abcd"
Output: false
Explanation: "abcd" cannot be rotated in any way to form a palindrome.

Input: s = "aab"
Output: true
Explanation: "aab" can be rotated 1 positions to the left (or 2 positions to the right) to obtain "aba", which is a palindrome.

Try It Yourself
redirect icon

[Brute-Force Approach] Try All Possible Rotations - O(n^2) Time and O(n) Space

The key thought is that any rotation of a string is always a substring of the original string concatenated with itself. So, we generate all possible rotated versions by sliding a window of size n over the concatenated string and check if any of them is a palindrome using two-pointer technique.

C++
#include <bits/stdc++.h>
using namespace std;

// Function to check if a string is palindrome
bool isPalindrome(string &s)
{
    int l = 0;
    int r = s.length() - 1;

    while (l < r)
    {
        if (s[l] != s[r])
        {
            return false;
        }
        l++;
        r--;
    }
    return true;
}

// Function to check if string is rotated palindrome
bool isRotatedPalindrome(string &s)
{
    int n = s.length();

    // Concatenate string with itself
    string concat = s + s;

    // Try every substring of length n
    // in the concatenated string
    for (int i = 0; i < n; i++)
    {
        // Extract substring of length n
        // starting from index i
        string sub = concat.substr(i, n);

        // Check if this substring is a palindrome
        if (isPalindrome(sub))
        {
            return true;
        }
    }

    return false;
}

int main()
{
    string s = "aaaab";

    if (isRotatedPalindrome(s) == true)
    {
        cout << "true" << endl;
    }
    else
    {
        cout << "false" << endl;
    }

    return 0;
}
Java
import java.util.*;

class GfG {

    // Function to check if a string is palindrome
    static boolean isPalindrome(String s)
    {
        int l = 0;
        int r = s.length() - 1;

        while (l < r) {
            if (s.charAt(l) != s.charAt(r)) {
                return false;
            }
            l++;
            r--;
        }
        return true;
    }

    // Function to check if string is rotated palindrome
    static boolean isRotatedPalindrome(String s)
    {
        int n = s.length();

        // Concatenate string with itself
        String concat = s + s;

        // Try every substring of length n
        // in the concatenated string
        for (int i = 0; i < n; i++) {

            // Extract substring of length n
            // starting from index i
            String sub = concat.substring(i, i + n);

            // Check if this substring is a palindrome
            if (isPalindrome(sub)) {
                return true;
            }
        }

        return false;
    }

    public static void main(String[] args)
    {
        String s = "aaaab";
        if (isRotatedPalindrome(s) == true) {
            System.out.println("true");
        }
        else {
            System.out.println("true");
        }
    }
}
Python
# Function to check if a string is palindrome
def isPalindrome(s):
    l = 0
    r = len(s) - 1

    while l < r:
        if s[l] != s[r]:
            return False
        l += 1
        r -= 1
    return True

# Function to check if string is rotated palindrome
def isRotatedPalindrome(s):

    n = len(s)

    # Concatenate string with itself
    concat = s + s

    # Try every substring of length n 
    # in the concatenated string
    for i in range(n):

        # Extract substring of length n 
        # starting from index i
        sub = concat[i:i + n]

        # Check if this substring is a palindrome
        if isPalindrome(sub):
            return True

    return False

# Driver Code
if __name__ == "__main__":

    s = "aaaab"
    if isRotatedPalindrome(s) == True:
        print("true")
    else:
        print("false")
C#
using System;

class GfG {

    // Function to check if a string is palindrome
    static bool isPalindrome(string s)
    {
        int l = 0;
        int r = s.Length - 1;

        while (l < r) {
            if (s[l] != s[r]) {
                return false;
            }
            l++;
            r--;
        }
        return true;
    }

    // Function to check if string is rotated palindrome
    static bool isRotatedPalindrome(string s)
    {
        int n = s.Length;

        // Concatenate string with itself
        string concat = s + s;

        // Try every substring of length n
        // in the concatenated string
        for (int i = 0; i < n; i++) {

            // Extract substring of length n
            // starting from index i
            string sub = concat.Substring(i, n);

            // Check if this substring is a palindrome
            if (isPalindrome(sub)) {
                return true;
            }
        }

        return false;
    }

    static void Main()
    {
        string s = "aaaab";
        if (isRotatedPalindrome(s) == true) {
            Console.WriteLine("true");
        }
        else {
            Console.WriteLine("false");
        }
    }
}
JavaScript
// Function to check if a string is palindrome
function isPalindrome(s)
{
    let l = 0;
    let r = s.length - 1;

    while (l < r) {
        if (s[l] !== s[r]) {
            return false;
        }
        l++;
        r--;
    }
    return true;
}

// Function to check if string is rotated palindrome
function isRotatedPalindrome(s)
{
    let n = s.length;

    // Concatenate string with itself
    let concat = s + s;

    // Try every substring of length n
    // in the concatenated string
    for (let i = 0; i < n; i++) {

        // Extract substring of length n
        // starting from index i
        let sub = concat.substring(i, i + n);

        // Check if this substring is a palindrome
        if (isPalindrome(sub)) {
            return true;
        }
    }

    return false;
}

// Driver Code
let s = "aaaab";
if (isRotatedPalindrome(s) == true) {
    console.log("true");
}
else {
    console.log("false");
}

Output
true

[Expected Approach] Using Manacher's Algorithm - O(n) Time and O(n) Space

  • Concatenate the original string with itself to simulate all possible rotations.
  • Preprocess the string by inserting special characters like '#' to handle even-length palindromes.
  • Initialize a length array P to store the radius of the palindrome centered at each index.
  • Use Manacher’s algorithm to expand around each center and fill the P array efficiently.
  • For every center, check if P[i] is at least equal to the original string's length.
  • If such a center exists, ensure the corresponding palindrome lies within the first 2n characters.
  • Return true if found, otherwise after the loop ends, return false as no valid rotation exists.
C++
#include <bits/stdc++.h>
using namespace std;

// Function to check if rotated palindrome
// exists using Manacher's Algorithm
bool isRotatedPalindrome(string &s)
{
    int n = s.length();

    // Concatenate the string with itself
    string concat = s + s;

    // Preprocess string for Manacher's algorithm
    // (insert '#' between characters)
    string t = "@";
    for (char c : concat)
    {
        t += "#" + string(1, c);
    }
    t += "#$";

    int m = t.length();
    vector<int> P(m, 0);
    int center = 0, right = 0;

    // Manacher's algorithm core loop
    for (int i = 1; i < m - 1; i++)
    {
        int mirror = 2 * center - i;

        if (i < right)
        {
            P[i] = min(right - i, P[mirror]);
        }

        // Try to expand palindrome centered at i
        while (t[i + (1 + P[i])] == t[i - (1 + P[i])])
        {
            P[i]++;
        }

        // Update center and right boundary
        if (i + P[i] > right)
        {
            center = i;
            right = i + P[i];
        }

        // Check if there's a palindrome of length n
        if (P[i] >= n)
        {
            // Position of start of palindrome
            // in original concat string
            int start = (i - P[i]) / 2;
            if (start + n <= 2 * n)
            {
                return true;
            }
        }
    }

    return false;
}

int main()
{
    string s = "aaaab";
    if (isRotatedPalindrome(s) == true)
    {
        cout << "true" << endl;
    }
    else
    {
        cout << "false" << endl;
    }

    return 0;
}
Java
class GfG {

    // Function to check if rotated palindrome
    // exists using Manacher's Algorithm
    static boolean isRotatedPalindrome(String s)
    {
        int n = s.length();

        // Concatenate the string with itself
        String concat = s + s;

        // Preprocess string for Manacher's algorithm
        // (insert '#' between characters)
        StringBuilder t = new StringBuilder("@");
        for (char c : concat.toCharArray()) {
            t.append("#").append(c);
        }
        t.append("#$");

        int m = t.length();
        int[] P = new int[m];
        int center = 0, right = 0;

        // Manacher's algorithm core loop
        for (int i = 1; i < m - 1; i++) {

            int mirror = 2 * center - i;

            if (i < right) {
                P[i] = Math.min(right - i, P[mirror]);
            }

            // Try to expand palindrome centered at i
            while (t.charAt(i + (1 + P[i]))
                   == t.charAt(i - (1 + P[i]))) {
                P[i]++;
            }

            // Update center and right boundary
            if (i + P[i] > right) {
                center = i;
                right = i + P[i];
            }

            // Check if there's a palindrome of length n
            if (P[i] >= n) {

                // Position of start of palindrome
                // in original concat string
                int start = (i - P[i]) / 2;
                if (start + n <= 2 * n) {
                    return true;
                }
            }
        }

        return false;
    }

    public static void main(String[] args)
    {
        String s = "aaaab";
        if (isRotatedPalindrome(s) == true) {
            System.out.println("true");
        }
        else {
            System.out.println("false");
        }
    }
}
Python
def isRotatedPalindrome(s):
    n = len(s)

    # Concatenate the string with itself
    concat = s + s

    # Preprocess string for Manacher's algorithm
    # (insert '#' between characters)
    t = "@"
    for c in concat:
        t += "#" + c
    t += "#$"

    m = len(t)
    P = [0] * m
    center = 0
    right = 0

    # Manacher's algorithm core loop
    for i in range(1, m - 1):
        mirror = 2 * center - i

        if i < right:
            P[i] = min(right - i, P[mirror])

        # Try to expand palindrome centered at i
        while t[i + (1 + P[i])] == t[i - (1 + P[i])]:
            P[i] += 1

        # Update center and right boundary
        if i + P[i] > right:
            center = i
            right = i + P[i]

        # Check if there's a palindrome of length n
        if P[i] >= n:

            # Position of start of palindrome
            # in original concat string
            start = (i - P[i]) // 2
            if start + n <= 2 * n:
                return True

    return False


# Driver Code
if __name__ == "__main__":
    s = "aaaab"
    if isRotatedPalindrome(s) == True:
        print("true")
    else:
        print("false")
C#
using System;

class GfG {

    // Function to check if rotated palindrome
    // exists using Manacher's Algorithm
    static bool isRotatedPalindrome(string s)
    {
        int n = s.Length;

        // Concatenate the string with itself
        string concat = s + s;

        // Preprocess string for Manacher's algorithm
        // (insert '#' between characters)
        string t = "@";
        foreach(char c in concat) { t += "#" + c; }
        t += "#$";

        int m = t.Length;
        int[] P = new int[m];
        int center = 0, right = 0;

        // Manacher's algorithm core loop
        for (int i = 1; i < m - 1; i++) {
            int mirror = 2 * center - i;

            if (i < right) {
                P[i] = Math.Min(right - i, P[mirror]);
            }

            // Try to expand palindrome centered at i
            while (t[i + (1 + P[i])] == t[i - (1 + P[i])]) {
                P[i]++;
            }

            // Update center and right boundary
            if (i + P[i] > right) {
                center = i;
                right = i + P[i];
            }

            // Check if there's a palindrome of length n
            if (P[i] >= n) {

                // Position of start of palindrome
                // in original concat string
                int start = (i - P[i]) / 2;
                if (start + n <= 2 * n) {
                    return true;
                }
            }
        }

        return false;
    }

    static void Main()
    {
        string s = "aaaab";
        if (isRotatedPalindrome(s) == true) {
            Console.WriteLine("true");
        }
        else {
            Console.WriteLine("false");
        }
    }
}
JavaScript
function isRotatedPalindrome(s)
{
    let n = s.length;

    // Concatenate the string with itself
    let concat = s + s;

    // Preprocess string for Manacher's algorithm
    // (insert '#' between characters)
    let t = "@";
    for (let c of concat) {
        t += "#" + c;
    }
    t += "#$";

    let m = t.length;
    let P = new Array(m).fill(0);
    let center = 0, right = 0;

    // Manacher's algorithm core loop
    for (let i = 1; i < m - 1; i++) {
        let mirror = 2 * center - i;

        if (i < right) {
            P[i] = Math.min(right - i, P[mirror]);
        }

        // Try to expand palindrome centered at i
        while (t[i + (1 + P[i])] === t[i - (1 + P[i])]) {
            P[i]++;
        }

        // Update center and right boundary
        if (i + P[i] > right) {
            center = i;
            right = i + P[i];
        }

        // Check if there's a palindrome of length n
        if (P[i] >= n) {
            // Position of start of palindrome
            // in original concat string
            let start = Math.floor((i - P[i]) / 2);
            if (start + n <= 2 * n) {
                return true;
            }
        }
    }

    return false;
}

// Driver Code
let s = "aaaab";
if (isRotatedPalindrome(s) == true) {
    console.log("true");
}
else {
    console.log("false");
}

Output
true
Comment