📜  将回文字符串转换为不同的回文字符串所需的最小切割

📅  最后修改于: 2021-10-26 06:43:45             🧑  作者: Mango

给定回文字符串s ,任务是找到最小k ,这样你就可以把这个字符串分成k+1 个部分,然后把它们联合起来,这样最终的字符串将是一个回文,它不会等于初始字符串s 。如果不可能,则打印-1
例子:

Input : string = "civic" 
Output : 2
Explanation : ci | v | ic --> ic | v | ci --> icvci

Input : string = "gggg"
Output : -1

Input : string = "redder" 
Output : 1
Explanation : red | der --> der | red --> derred

Input : string = "aaaasaaaa" 
Output : -1

方法一:给定形成的回文字符串应该与给定的字符串不同。
因此,当我们的字符串由 n 或 n-1 个(当 n 为奇数)相等的字符,就无法得到答案。例如 –

String : "aaaasaaaa"
String : "aaaa"

除了给定的字符串之外,以上字符串不能形成回文。
否则,剪切长度为l的 s 的最长前缀,该前缀由长度等于l-1的相等字符组成。现在同样切割长度为l-1 的后缀,并将剩余部分称为 mid。
现在我们有prefix = s[1..l]和 suff = s[(n-l+1)..n] 。交换前缀和后缀,然后将所有三个部分结合在一起并保持 mid 不变。

前缀 + 中 + 后缀\neq [Tex]后缀+中+前缀[/Tex]

很明显,我们可以通过两次切割得到答案。最后,您只需要检查是否有可能一次性得到答案。为此,只需从末尾剪下一个元素并将其附加在前面并继续此循环移位。在此期间,如果我们得到一个不同于给定字符串的回文字符串,那么这意味着我们只需一次切割就可以得到答案。
下面是上述方法的实现:

C++
// CPP program to solve the above problem
 
#include 
using namespace std;
 
// Function to check if string is palindrome or not
bool isPalindrome(string s)
{
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] != s[s.length() - i - 1]) {
            return false;
        }
    }
    return true;
}
 
// Function to check if it is possible to
// get result by making just one cut
bool ans(string s)
{
    string s2 = s;
 
    for (int i = 0; i < s.length(); ++i) {
        // Appending last element in front
        s2 = s2.back() + s2;
        // Removing last element
        s2.pop_back();
 
        // Checking whether string s2 is palindrome
        // and different from s.
        if (s != s2 && isPalindrome(s2)) {
            return true;
        }
    }
    return false;
}
 
int solve(string s)
{
    // If length is <=3 then it is impossible
    if (s.length() <= 3) {
        return -1;
    }
 
    // Array to store frequency of characters
    int cnt[25] = {};
 
    // Store count of characters in a array
    for (int i = 0; i < s.length(); i++) {
        cnt[s[i] - 'a']++;
    }
 
    // Condition for edge cases
    if (*max_element(cnt, cnt + 25) >= (s.length() - 1)) {
        return -1;
    }
    else {
        // Return 1 if it is possible to get palindromic
        // string in just one cut.
        // Else we can always reached in two cuttings.
        return (ans(s) ? 1 : 2);
    }
}
 
// Driver Code
int main()
{
 
    string s = "nolon";
 
    cout << solve(s);
 
    return 0;
}


Java
// Java program to solve the above problem
import java.util.Arrays;
 
class GFG
{
 
// Function to check if string is palindrome or not
static boolean isPalindrome(String s)
{
    for (int i = 0; i < s.length(); ++i)
    {
        if (s.charAt(i) != s.charAt(s.length() - i - 1))
        {
            return false;
        }
    }
    return true;
}
 
// Function to check if it is possible to
// get result by making just one cut
static boolean ans(String s)
{
    String s2 = s;
 
    for (int i = 0; i < s.length(); ++i)
    {
        // Appending last element in front
        s2 = s2.charAt(s2.length()-1) + s2;
         
        // Removing last element
        s2 = s2.substring(0,s2.length()-1);
 
        // Checking whether string s2 is palindrome
        // and different from s.
        if ((s == null ? s2 != null : !s.equals(s2)) &&
                                        isPalindrome(s2))
        {
            return true;
        }
    }
    return false;
}
 
static int solve(String s)
{
    // If length is <=3 then it is impossible
    if (s.length() <= 3)
    {
        return -1;
    }
 
    // Array to store frequency of characters
    int cnt[] = new int[25];
 
    // Store count of characters in a array
    for (int i = 0; i < s.length(); i++)
    {
        cnt[s.charAt(i) - 'a']++;
    }
 
    // Condition for edge cases
    if (Arrays.stream(cnt).max().getAsInt() >=
                                (s.length() - 1))
    {
        return -1;
    }
    else
    {
        // Return 1 if it is possible to get palindromic
        // string in just one cut.
        // Else we can always reached in two cuttings.
        return (ans(s) ? 1 : 2);
    }
}
 
// Driver Code
public static void main(String[] args)
{
        String s = "nolon";
        System.out.println(solve(s));
    }
}
 
// This code contributed by Rajput-Ji


Python3
# Python 3 program to solve the above problem
 
# Function to check if string is palindrome or not
def isPalindrome(s):
    for i in range(len(s)):
        if (s[i] != s[len(s) - i - 1]):
            return False
     
    return true
 
# Function to check if it is possible to
# get result by making just one cut
def ans(s):
    s2 = s
 
    for i in range(len(s)):
         
        # Appending last element in front
        s2 = s2[len(s2) - 1] + s2
         
        # Removing last element
        s2 = s2[0:len(s2) - 1]
 
        # Checking whether string s2 is palindrome
        # and different from s.
        if (s != s2 and isPalindrome(s2)):
            return True
     
    return False
 
def solve(s):
     
    # If length is <=3 then it is impossible
    if (len(s) <= 3):
        return -1
 
    # Array to store frequency of characters
    cnt = [0 for i in range(26)]
 
    # Store count of characters in a array
    for i in range(len(s)):
        cnt[ord(s[i]) - ord('a')] += 1
 
    # Condition for edge cases
    max = cnt[0]
    for i in range(len(cnt)):
        if cnt[i]>max:
            max = cnt[i]
    if (max >= len(s) - 1):
        return -1
     
    else:
         
        # Return 1 if it is possible to get
        # palindromic string in just one cut.
        # Else we can always reached in two cuttings.
        if ans(s) == True:
            return 1
        else:
            return 2
 
# Driver Code
if __name__ == '__main__':
    s = "nolon"
 
    print(solve(s))
     
# This code is contributed by
# Surendra_Gangwar


C#
// C# program to solve the above problem
using System;
using System.Linq;
 
class GFG
{
 
// Function to check if string is palindrome or not
static bool isPalindrome(string s)
{
    for (int i = 0; i < s.Length; ++i)
    {
        if (s[i] != s[s.Length - i - 1])
        {
            return false;
        }
    }
    return true;
}
 
// Function to check if it is possible to
// get result by making just one cut
static bool ans(string s)
{
    string s2 = s;
 
    for (int i = 0; i < s.Length; ++i)
    {
        // Appending last element in front
        s2 = s2[s2.Length-1] + s2;
         
        // Removing last element
        s2 = s2.Substring(0,s2.Length-1);
 
        // Checking whether string s2 is palindrome
        // and different from s.
        if ((s == null ? s2 != null : !s.Equals(s2)) &&
                                        isPalindrome(s2))
        {
            return true;
        }
    }
    return false;
}
 
static int solve(string s)
{
    // If length is <=3 then it is impossible
    if (s.Length <= 3)
    {
        return -1;
    }
 
    // Array to store frequency of characters
    int[] cnt = new int[25];
 
    // Store count of characters in a array
    for (int i = 0; i < s.Length; i++)
    {
        cnt[s[i] - 'a']++;
    }
 
    // Condition for edge cases
    if (cnt.Max() >=(s.Length - 1))
    {
        return -1;
    }
    else
    {
        // Return 1 if it is possible to get palindromic
        // string in just one cut.
        // Else we can always reached in two cuttings.
        return (ans(s) ? 1 : 2);
    }
}
 
// Driver Code
static void Main()
{
    string s = "nolon";
    Console.WriteLine(solve(s));
}
}
 
// This code contributed by mits


Javascript


C++
// CPP program to solve the above problem
 
#include 
using namespace std;
 
// Recursive function to find minimum number
// of cuts if length of string is even
int solveEven(string s)
{
    // If length is odd then return 2
    if (s.length() % 2 == 1)
        return 2;
 
    // To check if half of palindromic string
    // is itself a palindrome
    string ls = s.substr(0, s.length() / 2);
 
    string rs = s.substr(s.length() / 2, s.length());
 
    // If not then return 1
    if (ls != rs)
        return 1;
 
    // Else call function with half palindromic string
    return solveEven(ls);
}
 
// Function to find minimum number of cuts
// If length of string is odd
int solveOdd(string s)
{
    return 2;
}
 
int solve(string s)
{
    // If length is <=3 then it is impossible
    if (s.length() <= 3) {
        return -1;
    }
 
    // Array to store frequency of characters
    int cnt[25] = {};
 
    // Store count of characters in a array
    for (int i = 0; i < s.length(); i++) {
        cnt[s[i] - 'a']++;
    }
 
    // Condition for edge cases
    if (*max_element(cnt, cnt + 25) >= s.length() - 1) {
        return -1;
    }
 
    // If length is even
    if (s.length() % 2 == 0)
        return solveEven(s);
 
    // If length is odd
    if (s.length() % 2 == 1)
        return solveOdd(s);
}
 
// Driver Code
int main()
{
    string s = "nolon";
 
    cout << solve(s);
 
    return 0;
}


Java
// Java program to solve the above problem
import java.util.Arrays;
 
class GFG
{
 
    // Recursive function to find minimum number
    // of cuts if length of String is even
    static int solveEven(String s)
    {
        // If length is odd then return 2
        if (s.length() % 2 == 1)
        {
            return 2;
        }
 
        // To check if half of palindromic String
        // is itself a palindrome
        String ls = s.substring(0, s.length() / 2);
 
        String rs = s.substring(s.length() / 2, s.length());
 
        // If not then return 1
        if (ls != rs)
        {
            return 1;
        }
 
        // Else call function with half palindromic String
        return solveEven(ls);
    }
 
    // Function to find minimum number of cuts
    // If length of String is odd
    static int solveOdd(String s)
    {
        return 2;
    }
 
    static int solve(String s)
    {
        // If length is <=3 then it is impossible
        if (s.length() <= 3)
        {
            return -1;
        }
 
        // Array to store frequency of characters
        int cnt[] = new int[25];
 
        // Store count of characters in a array
        for (int i = 0; i < s.length(); i++)
        {
            cnt[s.charAt(i) - 'a']++;
        }
 
        // Condition for edge cases
        if (Arrays.stream(cnt).max().getAsInt() >= s.length() - 1)
        {
            return -1;
        }
 
        // If length is even
        if (s.length() % 2 == 0)
        {
            return solveEven(s);
        }
 
        // If length is odd
        if (s.length() % 2 == 1)
        {
            return solveOdd(s);
        }
        return Integer.MIN_VALUE;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String s = "nolon";
        System.out.println(solve(s));
    }
}
 
// This code has been contributed by 29AjayKumar


Python3
# Python3 program to solve the above problem
 
# Recursive function to find minimum number
# of cuts if length of string is even
def solveEven(s):
 
    # If length is odd then return 2
    if len(s) % 2 == 1:
        return 2
 
    # To check if half of palindromic
    # string is itself a palindrome
    ls = s[0 : len(s) // 2]
    rs = s[len(s) // 2 : len(s)]
 
    # If not then return 1
    if ls != rs:
        return 1
 
    # Else call function with
    # half palindromic string
    return solveEven(ls)
 
# Function to find minimum number of cuts
# If length of string is odd
def solveOdd(s):
    return 2
 
def solve(s):
 
    # If length is <=3 then it is impossible
    if len(s) <= 3:
        return -1
     
    # Array to store frequency of characters
    cnt = [0] * 25
 
    # Store count of characters in a array
    for i in range(0, len(s)):
        cnt[ord(s[i]) - ord('a')] += 1
     
    # Condition for edge cases
    if max(cnt) >= len(s) - 1:
        return -1
     
    # If length is even
    if len(s) % 2 == 0:
        return solveEven(s)
 
    # If length is odd
    if len(s) % 2 == 1:
        return solveOdd(s)
 
# Driver Code
if __name__ == "__main__":
 
    s = "nolon"
    print(solve(s))
 
# This code is contributed by Rituraj Jain


C#
// C# program to solve the above problem
using System;
using System.Linq;
 
class GFG
{
 
    // Recursive function to find minimum number
    // of cuts if length of String is even
    static int solveEven(String s)
    {
        // If length is odd then return 2
        if (s.Length % 2 == 1)
        {
            return 2;
        }
 
        // To check if half of palindromic String
        // is itself a palindrome
        String ls = s.Substring(0, s.Length / 2);
 
        String rs = s.Substring(s.Length / 2, s.Length);
 
        // If not then return 1
        if (ls != rs)
        {
            return 1;
        }
 
        // Else call function with half palindromic String
        return solveEven(ls);
    }
 
    // Function to find minimum number of cuts
    // If length of String is odd
    static int solveOdd(String s)
    {
        return 2;
    }
 
    static int solve(String s)
    {
        // If length is <=3 then it is impossible
        if (s.Length <= 3)
        {
            return -1;
        }
 
        // Array to store frequency of characters
        int []cnt = new int[25];
 
        // Store count of characters in a array
        for (int i = 0; i < s.Length; i++)
        {
            cnt[s[i] - 'a']++;
        }
 
        // Condition for edge cases
        if (cnt.Max() >= s.Length - 1)
        {
            return -1;
        }
 
        // If length is even
        if (s.Length % 2 == 0)
        {
            return solveEven(s);
        }
 
        // If length is odd
        if (s.Length % 2 == 1)
        {
            return solveOdd(s);
        }
        return int.MinValue;
    }
 
    // Driver Code
    public static void Main()
    {
        String s = "nolon";
        Console.WriteLine(solve(s));
    }
}
 
/* This code contributed by PrinciRaj1992 */


Javascript


输出:
2

时间复杂度: O(N 2 )
有效的方法:同样,如果我们的字符串由 n 或 n-1(当 n 为奇数)相等的字符,那么就没有办法得到答案。
现在,把这个问题分成两部分,字符串长度是偶数还是奇数
如果字符串长度是奇数,那么我们总是有一个中间元素,所以只需在中间元素周围切割 2 次并将字符串分成三段并交换第一段和第三段。
说,我们有一个字符串:

nolon --> no | l | on --> on | l | no --> onlno

如果字符串长度是偶数,则检查半字符串本身是否是回文字符串。
如果是这样:

  1. 将字符串递归拆分为两部分,并检查生成的半字符串是否为回文。
  2. 如果字符串变成奇数长度,则只需返回 2。
asaasa --> as | aa | sa --> sa | aa | as --> saaaas
  1. 如果结果字符串不是回文,则返回 1。
toottoot --> to | ottoot --> ottoot | to --> ottootto

否则我们可以从中间剪下这个字符串,形成两段并相互交换。
例如

voov --> vo | ov --> ov | vo --> ovvo

下面是上述方法的实现:

C++

// CPP program to solve the above problem
 
#include 
using namespace std;
 
// Recursive function to find minimum number
// of cuts if length of string is even
int solveEven(string s)
{
    // If length is odd then return 2
    if (s.length() % 2 == 1)
        return 2;
 
    // To check if half of palindromic string
    // is itself a palindrome
    string ls = s.substr(0, s.length() / 2);
 
    string rs = s.substr(s.length() / 2, s.length());
 
    // If not then return 1
    if (ls != rs)
        return 1;
 
    // Else call function with half palindromic string
    return solveEven(ls);
}
 
// Function to find minimum number of cuts
// If length of string is odd
int solveOdd(string s)
{
    return 2;
}
 
int solve(string s)
{
    // If length is <=3 then it is impossible
    if (s.length() <= 3) {
        return -1;
    }
 
    // Array to store frequency of characters
    int cnt[25] = {};
 
    // Store count of characters in a array
    for (int i = 0; i < s.length(); i++) {
        cnt[s[i] - 'a']++;
    }
 
    // Condition for edge cases
    if (*max_element(cnt, cnt + 25) >= s.length() - 1) {
        return -1;
    }
 
    // If length is even
    if (s.length() % 2 == 0)
        return solveEven(s);
 
    // If length is odd
    if (s.length() % 2 == 1)
        return solveOdd(s);
}
 
// Driver Code
int main()
{
    string s = "nolon";
 
    cout << solve(s);
 
    return 0;
}

Java

// Java program to solve the above problem
import java.util.Arrays;
 
class GFG
{
 
    // Recursive function to find minimum number
    // of cuts if length of String is even
    static int solveEven(String s)
    {
        // If length is odd then return 2
        if (s.length() % 2 == 1)
        {
            return 2;
        }
 
        // To check if half of palindromic String
        // is itself a palindrome
        String ls = s.substring(0, s.length() / 2);
 
        String rs = s.substring(s.length() / 2, s.length());
 
        // If not then return 1
        if (ls != rs)
        {
            return 1;
        }
 
        // Else call function with half palindromic String
        return solveEven(ls);
    }
 
    // Function to find minimum number of cuts
    // If length of String is odd
    static int solveOdd(String s)
    {
        return 2;
    }
 
    static int solve(String s)
    {
        // If length is <=3 then it is impossible
        if (s.length() <= 3)
        {
            return -1;
        }
 
        // Array to store frequency of characters
        int cnt[] = new int[25];
 
        // Store count of characters in a array
        for (int i = 0; i < s.length(); i++)
        {
            cnt[s.charAt(i) - 'a']++;
        }
 
        // Condition for edge cases
        if (Arrays.stream(cnt).max().getAsInt() >= s.length() - 1)
        {
            return -1;
        }
 
        // If length is even
        if (s.length() % 2 == 0)
        {
            return solveEven(s);
        }
 
        // If length is odd
        if (s.length() % 2 == 1)
        {
            return solveOdd(s);
        }
        return Integer.MIN_VALUE;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String s = "nolon";
        System.out.println(solve(s));
    }
}
 
// This code has been contributed by 29AjayKumar

蟒蛇3

# Python3 program to solve the above problem
 
# Recursive function to find minimum number
# of cuts if length of string is even
def solveEven(s):
 
    # If length is odd then return 2
    if len(s) % 2 == 1:
        return 2
 
    # To check if half of palindromic
    # string is itself a palindrome
    ls = s[0 : len(s) // 2]
    rs = s[len(s) // 2 : len(s)]
 
    # If not then return 1
    if ls != rs:
        return 1
 
    # Else call function with
    # half palindromic string
    return solveEven(ls)
 
# Function to find minimum number of cuts
# If length of string is odd
def solveOdd(s):
    return 2
 
def solve(s):
 
    # If length is <=3 then it is impossible
    if len(s) <= 3:
        return -1
     
    # Array to store frequency of characters
    cnt = [0] * 25
 
    # Store count of characters in a array
    for i in range(0, len(s)):
        cnt[ord(s[i]) - ord('a')] += 1
     
    # Condition for edge cases
    if max(cnt) >= len(s) - 1:
        return -1
     
    # If length is even
    if len(s) % 2 == 0:
        return solveEven(s)
 
    # If length is odd
    if len(s) % 2 == 1:
        return solveOdd(s)
 
# Driver Code
if __name__ == "__main__":
 
    s = "nolon"
    print(solve(s))
 
# This code is contributed by Rituraj Jain

C#

// C# program to solve the above problem
using System;
using System.Linq;
 
class GFG
{
 
    // Recursive function to find minimum number
    // of cuts if length of String is even
    static int solveEven(String s)
    {
        // If length is odd then return 2
        if (s.Length % 2 == 1)
        {
            return 2;
        }
 
        // To check if half of palindromic String
        // is itself a palindrome
        String ls = s.Substring(0, s.Length / 2);
 
        String rs = s.Substring(s.Length / 2, s.Length);
 
        // If not then return 1
        if (ls != rs)
        {
            return 1;
        }
 
        // Else call function with half palindromic String
        return solveEven(ls);
    }
 
    // Function to find minimum number of cuts
    // If length of String is odd
    static int solveOdd(String s)
    {
        return 2;
    }
 
    static int solve(String s)
    {
        // If length is <=3 then it is impossible
        if (s.Length <= 3)
        {
            return -1;
        }
 
        // Array to store frequency of characters
        int []cnt = new int[25];
 
        // Store count of characters in a array
        for (int i = 0; i < s.Length; i++)
        {
            cnt[s[i] - 'a']++;
        }
 
        // Condition for edge cases
        if (cnt.Max() >= s.Length - 1)
        {
            return -1;
        }
 
        // If length is even
        if (s.Length % 2 == 0)
        {
            return solveEven(s);
        }
 
        // If length is odd
        if (s.Length % 2 == 1)
        {
            return solveOdd(s);
        }
        return int.MinValue;
    }
 
    // Driver Code
    public static void Main()
    {
        String s = "nolon";
        Console.WriteLine(solve(s));
    }
}
 
/* This code contributed by PrinciRaj1992 */

Javascript


输出:
2

时间复杂度: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程