📜  最小割需要一个回文字符串转换为不同的回文字符串

📅  最后修改于: 2021-04-22 02:43:52             🧑  作者: 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

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

String : "aaaasaaaa"
String : "aaaa"

除了给定的字符串以外,上面的字符串不能形成回文。
否则,切长度l,即由长度等于字符的S的最长前缀等于L-1。现在类似地削减长度为l-1的后缀,并将其余部分称为中点。

现在我们有了前缀= s [1..l]和suff = s [(n-l + 1).. n] 。交换前缀和后缀,然后将所有三个部分组合在一起,并保持中间位置不变。

前缀+中间+后缀\neq后缀+中间+前缀

因此,很明显,我们可以通过两次削减获得答案。最后,您只需要检查是否可以一口气得到答案。为此,只需从末尾剪切一个元素并将其附加在前面,然后继续进行此循环移位即可。在此期间,如果我们得到的回文字符串不是给定的回文字符串,则意味着我们可以一口气得到答案。

下面是上述方法的实现:

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


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


输出:
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
  3. 如果结果字符串不是回文,则返回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

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 */
输出:
2

时间复杂度: O(N)