Minimum cuts required to convert a palindromic string to a different palindromic string

Given palindromic string s, the task is to find minimum k, such that you can cut this string into k+1 parts, and then unite them in such a way that the final string will be a palindrome and it won’t be equal to the initial string s. If it is impossible then print -1.
Examples:Â
Â
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
Â
Approach 1: It is given that formed palindromic string should be different from the given string.Â
So when our string consists of n or n-1 (when n is odd) equal characters, then there is no way to get the answer. For example –Â
Â
String : "aaaasaaaa" String : "aaaa"
Above strings can not form palindrome other than the given one.Â
Otherwise, cut the longest prefix of s of length l, that consists of equal characters of length equal to l-1. Now similarly cut suffix of length l-1, and call remaining part as mid.
Now we have prefix = s[1..l] and suff = s[(n-l+1)..n]. Swap prefix and suffix, then unite all three parts together and keep mid as it is.Â
Â
prefix + mid + suffix[Tex]suffix + mid + prefix[/Tex]
So clearly we can get the answer in two cuts. Finally you just have to check if it is possible to get answer in one cut. For that just cut one element from end and append it at front and continue this cyclic shift. During this if we get a palindromic string other then the given one then it means we can get answer in just one cut.
Below is the implementation of above approach:Â
Â
C++
// CPP program to solve the above problemÂ
#include <bits/stdc++.h>using namespace std;Â
// Function to check if string is palindrome or notbool 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 cutbool 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 Codeint main(){Â
    string s = "nolon";Â
    cout << solve(s);Â
    return 0;} |
Java
// Java program to solve the above problemimport java.util.Arrays;Â
class GFG{Â
// Function to check if string is palindrome or notstatic 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 cutstatic 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 Codepublic 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 notdef 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 cutdef 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 Codeif __name__ == '__main__':Â Â Â Â s = "nolon"Â
    print(solve(s))     # This code is contributed by# Surendra_Gangwar |
C#
// C# program to solve the above problemusing System;using System.Linq;Â
class GFG{Â
// Function to check if string is palindrome or notstatic 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 cutstatic 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 Codestatic void Main() {Â Â Â Â string s = "nolon";Â Â Â Â Console.WriteLine(solve(s));}}Â
// This code contributed by mits |
Javascript
<script>Â
// JavaScript program to solve the above problemÂ
// Function to check if string is palindrome or notfunction isPalindrome(s){Â Â Â Â for (let 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 cutfunction ans(s){    let s2 = s;       for (let 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 == (s2)) &&                                         isPalindrome(s2))        {            return true;        }    }    return false;}Â
function solve(s){    // If length is <=3 then it is impossible    if (s.length <= 3)     {        return -1;    }       // Array to store frequency of characters    let cnt = new Array(25);    for(let i=0;i<25;i++)        cnt[i]=0;       // Store count of characters in a array    for (let i = 0; i < s.length; i++)     {        cnt[s[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;    }       // Condition for edge cases    if (Math.max(...cnt) >= (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 Codelet s = "nolon";document.write(solve(s));Â
// This code is contributed by rag2127Â
</script> |
2
Â
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: Again if our string consists of n or n-1 (when n is odd) equal characters, then there is no way to get the answer.Â
Now, divide this problem into two parts that whether the string length is even or odd.Â
If the string length is odd then we always have a middle element in it so just make 2 cuts around the middle element and split the string into three segments and swap first and third segments.Â
Say, we have a string:Â
Â
nolon --> no | l | on --> on | l | no --> onlno
If the string length is even then check whether the half string is itself a palindromic string or not.Â
If so then:Â
Â
- Split a string recursively into two parts and check whether the resulting half string is a palindrome or not.
- If string became of odd length then simply return 2.Â
Â
asaasa --> as | aa | sa --> sa | aa | as --> saaaas
- If resulting string is not a palindrome then return 1.Â
Â
toottoot --> to | ottoot --> ottoot | to --> ottootto
Else we can cut this string from the middle, form two segments and swap each other.Â
For Example:Â
Â
voov --> vo | ov --> ov | vo --> ovvo
Below is the implementation of above approach:Â
Â
C++
// CPP program to solve the above problemÂ
#include <bits/stdc++.h>using namespace std;Â
// Recursive function to find minimum number // of cuts if length of string is evenint 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 oddint 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 Codeint 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 problemusing 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
<script>// Javascript program to solve the above problemÂ
// Recursive function to find minimum number    // of cuts if length of String is evenfunction solveEven(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        let ls = s.substring(0, s.length / 2);          let 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 oddfunction solveOdd(s){    return 2;}Â
function solve(s){    // If length is <=3 then it is impossible        if (s.length <= 3)        {            return -1;        }          // Array to store frequency of characters        let cnt = new Array(25);        for(let i=0;i<25;i++)            cnt[i]=0;          // Store count of characters in a array        for (let i = 0; i < s.length; i++)        {            cnt[s[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;        }          // Condition for edge cases        if (Math.max(...cnt) >= 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 Number.MIN_VALUE;}Â
// Driver Codelet s = "nolon";document.write(solve(s));Â
// This code is contributed by avanitrachhadiya2155</script> |
2
Â
Time Complexity : O(N)
Auxiliary Space: O(max(26,N))
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



