📜  查找字符串是否为K回文|套装2

📅  最后修改于: 2021-04-29 18:08:18             🧑  作者: Mango

给定一个字符串,请确定该字符串是否为K-Palindrome。在从中删除最多k个字符,K回文字符串将转换为回文。

例子:

Input : String - abcdecba, k = 1
Output : Yes
String can become palindrome by removing
1 character i.e. either d or e

Input  : String - abcdeca, K = 2
Output : Yes
Can become palindrome by removing
2 characters b and e (or b and d).

Input : String - acdcb, K = 1
Output : No
String can not become palindrome by
removing only one character.

我们在上一篇文章中讨论了DP解决方案,我们发现该问题基本上是Edit Distance问题的一种变体。在这篇文章中,讨论了另一个有趣的DP解决方案。

这个想法是找到给定弦的最长回文子字符串。如果最长回文子序列与原始字符串之间的差小于等于k,则该字符串为k回文,否则不是k回文。

例如,字符串abcdeca的最长回文子序列acdca (或aceca)。这无助于字符串的最长的回文序列的字符应该为了使字符串回文被删除。因此,在从abcdeca中删除b和d(或e)时,字符串将转换为回文。

字符串的最长回文子序列可以使用LCS轻松找到。以下是找到使用LCS的最长回文子序列的两步解决方案。

  1. 反转给定序列并将反转存储在另一个数组中,例如rev [0..n-1]
  2. 给定序列和rev []的LCS将是最长回文序列。

以下是上述想法的实现–

CPP
// C++ program to find if given string is K-Palindrome
// or not
#include 
using namespace std;
  
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int lcs( string X, string Y, int m, int n )
{
    int L[m + 1][n + 1];
  
    /* Following steps build L[m+1][n+1] in bottom up
        fashion. Note that L[i][j] contains length of
        LCS of X[0..i-1] and Y[0..j-1] */
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            if (i == 0 || j == 0)
                L[i][j] = 0;
            else if (X[i - 1] == Y[j - 1])
                L[i][j] = L[i - 1][j - 1] + 1;
            else
                L[i][j] = max(L[i - 1][j], L[i][j - 1]);
        }
    }
    // L[m][n] contains length of LCS for X and Y
    return L[m][n];
}
  
// find if given string is K-Palindrome or not
bool isKPal(string str, int k)
{
    int n = str.length();
  
    // Find reverse of string
    string revStr = str;
    reverse(revStr.begin(), revStr.end());
  
    // find longest palindromic subsequence of
    // given string
    int lps = lcs(str, revStr, n, n);
  
    // If the difference between longest palindromic
    // subsequence and the original string is less
    // than equal to k, then the string is k-palindrome
    return (n - lps <= k);
}
  
// Driver program
int main()
{
    string str = "abcdeca";
    int k = 2;
    isKPal(str, k) ? cout << "Yes" : cout << "No";
  
    return 0;
}


Java
// Java program to find if given  
// String is K-Palindrome or not
class GFG 
{
  
    /* Returns length of LCS for
    X[0..m-1], Y[0..n-1] */
    static int lcs(String X, String Y,
                        int m, int n) 
    {
        int L[][] = new int[m + 1][n + 1];
  
        /* Following steps build L[m+1][n+1]
        in bottom up fashion. Note that L[i][j] 
        contains length of LCS of X[0..i-1]
        and Y[0..j-1] */
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++) 
            {
                if (i == 0 || j == 0) 
                {
                    L[i][j] = 0;
                } 
                else if (X.charAt(i - 1) == Y.charAt(j - 1))
                {
                    L[i][j] = L[i - 1][j - 1] + 1;
                } 
                else
                {
                    L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]);
                }
            }
        }
        // L[m][n] contains length 
        // of LCS for X and Y 
        return L[m][n];
    }
  
    // find if given String is
    // K-Palindrome or not 
    static boolean isKPal(String str, int k) 
    {
        int n = str.length();
  
        // Find reverse of String 
        StringBuilder revStr = new StringBuilder(str);
        revStr = revStr.reverse();
  
        // find longest palindromic 
        // subsequence of given String 
        int lps = lcs(str, revStr.toString(), n, n);
  
        // If the difference between longest  
        // palindromic subsequence and the  
        // original String is less than equal 
        // to k, then the String is k-palindrome 
        return (n - lps <= k);
    }
  
    // Driver code 
    public static void main(String[] args) 
    {
        String str = "abcdeca";
        int k = 2;
        if (isKPal(str, k))
        {
            System.out.println("Yes");
        }
        else
            System.out.println("No");
    }
}
  
// This code is contributed by Rajput-JI


Python3
# Python program to find
# if given string is K-Palindrome
# or not
  
# Returns length of LCS
# for X[0..m-1], Y[0..n-1] 
def lcs(X, Y, m, n ):
  
    L = [[0]*(n+1) for _ in range(m+1)]
  
    # Following steps build
        # L[m+1][n+1] in bottom up
        # fashion. Note that L[i][j]
        # contains length of
    # LCS of X[0..i-1] and Y[0..j-1] 
    for i in range(m+1):
        for j in range(n+1):
            if not i or not j:
                L[i][j] = 0
            elif X[i - 1] == Y[j - 1]:
                L[i][j] = L[i - 1][j - 1] + 1
            else:
                L[i][j] = max(L[i - 1][j], L[i][j - 1])
  
    # L[m][n] contains length
        # of LCS for X and Y
    return L[m][n]
  
# find if given string is
# K-Palindrome or not
def isKPal(string, k):
  
    n = len(string)
  
    # Find reverse of string
    revStr = string[::-1]
  
    # find longest palindromic
        # subsequence of
    # given string
    lps = lcs(string, revStr, n, n)
  
    # If the difference between
        # longest palindromic
    # subsequence and the original
        # string is less
    # than equal to k, then
        # the string is k-palindrome
    return (n - lps <= k)
  
# Driver program
string = "abcdeca"
k = 2
  
print("Yes" if isKPal(string, k) else "No")
  
# This code is contributed
# by Ansu Kumari.


C#
// C# program to find if given 
// String is K-Palindrome or not 
using System;
  
class GFG 
{ 
  
    /* Returns length of LCS for 
    X[0..m-1], Y[0..n-1] */
    static int lcs(String X, String Y, 
                        int m, int n) 
    { 
        int [,]L = new int[m + 1,n + 1]; 
  
        /* Following steps build L[m+1,n+1] 
        in bottom up fashion. Note that L[i,j] 
        contains length of LCS of X[0..i-1] 
        and Y[0..j-1] */
        for (int i = 0; i <= m; i++) 
        { 
            for (int j = 0; j <= n; j++) 
            { 
                if (i == 0 || j == 0) 
                { 
                    L[i, j] = 0; 
                } 
                else if (X[i - 1] == Y[j - 1]) 
                { 
                    L[i, j] = L[i - 1, j - 1] + 1; 
                } 
                else
                { 
                    L[i, j] = Math.Max(L[i - 1, j],
                                        L[i, j - 1]); 
                } 
            } 
        } 
          
        // L[m,n] contains length 
        // of LCS for X and Y 
        return L[m, n]; 
    } 
  
    // find if given String is 
    // K-Palindrome or not 
    static bool isKPal(String str, int k) 
    { 
        int n = str.Length; 
  
        // Find reverse of String 
        str = reverse(str); 
  
        // find longest palindromic 
        // subsequence of given String 
        int lps = lcs(str, str, n, n); 
  
        // If the difference between longest 
        // palindromic subsequence and the 
        // original String is less than equal 
        // to k, then the String is k-palindrome 
        return (n - lps <= k); 
    } 
    static String reverse(String input)
    {
        char[] temparray = input.ToCharArray();
        int left, right = 0;
        right = temparray.Length - 1;
  
        for (left = 0; left < right; left++, right--) 
        {
              
            // Swap values of left and right 
            char temp = temparray[left];
            temparray[left] = temparray[right];
            temparray[right] = temp;
        }
        return String.Join("",temparray);
    }
      
    // Driver code 
    public static void Main(String[] args) 
    { 
        String str = "abcdeca"; 
        int k = 2; 
        if (isKPal(str, k)) 
        { 
            Console.WriteLine("Yes"); 
        } 
        else
            Console.WriteLine("No"); 
    } 
} 
  
// This code is contributed by PrinciRaj1992


输出:

Yes

上述解决方案的时间复杂度为O(n 2 )。
该程序使用的辅助空间为O(n 2 )。通过使用LCS的空间优化解决方案,可以将其进一步降低为O(n)。

感谢Ravi Teja Kaveti提供上述解决方案。