📌  相关文章
📜  检查给定的字符串是否是回文的旋转

📅  最后修改于: 2022-05-13 01:57:07.124000             🧑  作者: Mango

检查给定的字符串是否是回文的旋转

给定一个字符串,检查它是否是回文的旋转。例如,您的函数应该为“aab”返回 true,因为它是“aba”的旋转。
例子:

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.

我们强烈建议您单击此处并进行练习,然后再继续使用解决方案。

一个简单的解决方案是获取输入字符串,尝试它的每一个可能的旋转,如果旋转是回文则返回 true。如果没有旋转是回文,则返回 false。
以下是该方法的实现。

C++
#include 
#include 
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 itself 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;
}


Java
// 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 itself 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


Python3
# 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 range(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


C#
// 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 itself 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


Javascript


C++
// C++ implementation of the approach
#include 
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


Java
// 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


Python3
# Python implementation of the approach
 
# Function to check if we have found
# a palindrome of same length as the input
# which is a rotation of the input string
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
 
# Function to preprocess the string
# for Manacher's Algorithm
def reform (s):
 
    s1 = "$#"
 
    # Adding '#' between the characters
    for i in range(len(s)):
        s1 += s[i]
        s1 += "#"
 
    s1 += "@"
    return s1
 
# Function to find the longest palindromic
# substring using Manacher's Algorithm
def longestPal (s, Len):
 
    # Current Left Position
    mirror = 0
   
    # Center Right Position
    R = 0
   
    # Center Position
    C = 0
   
    # LPS Length Array
    P = [0] * len(s)
    x = 0
   
    # Get currentLeftPosition Mirror
    # for currentRightPosition i
    for i in range(1, len(s) - 1):
        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] += 1
 
        # Check for palindrome
        ans = checkPal(P[i], Len)
        if (ans):
            return True
         
        # If palindrome centered at current
        # RightPosition 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
if __name__ == '__main__':
     
    s = "aaaad"
    Len = len(s)
    s += s
    s = reform(s)
    print(longestPal(s, Len))
 
# This code is contributed by himanshu77


C#
// 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


Javascript


输出:

1
0
1

时间复杂度: O(n 2 )
辅助空间:O(n) 用于存储旋转。
请注意,上述算法可以优化为在 O(1) 额外空间中工作,因为我们可以在 O(n) 时间和 O(1) 额外空间中旋转字符串。
优化的解决方案可以在 O(n) 时间内工作。这里的想法是使用 Manacher 的算法来解决上述问题。

  • 让给定的字符串为's',字符串的长度为'n'。
  • 预处理/准备字符串以使用 Manachers 算法,以帮助找到偶数长度的回文,为此我们将给定的字符串与自身连接(以查找旋转是否会给出回文)并在开头添加“$”符号和“#”字符字母之间。我们使用'@'结束字符串。所以对于 'aaad' 输入,重组后的字符串将是 - '$#a#a#a#a#d#a#a#a#a#d#@'
  • 现在问题简化为使用长度为 n 或更大的 Manacher 算法在 string 中查找最长回文子字符串。
  • 如果存在长度为 n 的回文子串,则返回 true,否则返回 false。如果我们找到一个更大长度的回文,那么我们检查输入的大小是偶数还是奇数,相应地我们找到的回文长度也应该是偶数或奇数。

例如。如果我们的输入大小是 3,并且在执行 Manacher 算法时,我们得到一个大小为 5 的回文,它显然将包含一个大小为 3 的子串,这是一个回文,但对于长度为 4 的回文则不能这样说。因此我们检查是否在任何情况下,输入的大小和回文的大小都是偶数或奇数。
边界情况将是一个具有相同字母的单词,它会违反上述属性,但在这种情况下,我们的算法会发现偶数长度和奇数长度回文,其中一个是子字符串,因此不会有问题。
下面是上述算法的实现:

C++

// C++ implementation of the approach
#include 
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

Java

// 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

Python3

# Python implementation of the approach
 
# Function to check if we have found
# a palindrome of same length as the input
# which is a rotation of the input string
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
 
# Function to preprocess the string
# for Manacher's Algorithm
def reform (s):
 
    s1 = "$#"
 
    # Adding '#' between the characters
    for i in range(len(s)):
        s1 += s[i]
        s1 += "#"
 
    s1 += "@"
    return s1
 
# Function to find the longest palindromic
# substring using Manacher's Algorithm
def longestPal (s, Len):
 
    # Current Left Position
    mirror = 0
   
    # Center Right Position
    R = 0
   
    # Center Position
    C = 0
   
    # LPS Length Array
    P = [0] * len(s)
    x = 0
   
    # Get currentLeftPosition Mirror
    # for currentRightPosition i
    for i in range(1, len(s) - 1):
        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] += 1
 
        # Check for palindrome
        ans = checkPal(P[i], Len)
        if (ans):
            return True
         
        # If palindrome centered at current
        # RightPosition 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
if __name__ == '__main__':
     
    s = "aaaad"
    Len = len(s)
    s += s
    s = reform(s)
    print(longestPal(s, Len))
 
# This code is contributed by himanshu77

C#

// 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

Javascript


输出:
1