📌  相关文章
📜  查找字符串是否为 K-Palindrome |设置 1

📅  最后修改于: 2021-09-17 06:43:42             🧑  作者: Mango

给定一个字符串,判断该字符串是否为 K-Palindrome。一个 k 回文字符串转换为一个回文,最多删除 k 个字符。
例子 :

Input : String - abcdecba, k = 1
Output : Yes
String can become palindrome by remo-
-ving 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.

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

如果我们仔细分析这个问题,任务是通过从中删除最多 K 个字符来将给定的字符串转换为其反向。问题基本上是编辑距离的变化。我们可以修改编辑距离问题以将给定的字符串及其反向作为输入,并且只允许删除操作。由于给定的字符串与其反向进行比较,我们最多将从第一个字符串删除 N 个,从第二个字符串删除 N 个,以使它们相等。因此,对于要成为 k 回文的字符串,2*N <= 2*K 应该成立。
以下是算法的详细步骤——
从两个字符串的左侧或右侧开始,一个一个地处理所有字符。让我们从右角开始遍历,每对被遍历的字符都有两种可能性。

  1. 如果两个字符串的最后一个字符相同,我们忽略最后一个字符并计算剩余字符串的计数。所以我们重复长度为 m-1 和 n-1,其中 m 是 str1 的长度,n 是 str2 的长度。
  2. 如果最后一个字符是不一样的,我们考虑在第一字符串和第二字符串的最后一个字符,递归计算最低成本运作的最后一个字符删除操作,并取两个值的最小值。
    • 从 str1 中删除最后一个字符:重复 m-1 和 n。
    • 从 str2 中删除最后一个字符:对 m 和 n-1 重复。

下面是上述方法的朴素递归实现。

C++
// A Naive recursive C++ program to find
// if given string is K-Palindrome or not
#include
using namespace std;
 
// find if given string is K-Palindrome or not
int isKPalRec(string str1, string str2, int m, int n)
{
    // If first string is empty, the only option is to
    // remove all characters of second string
    if (m == 0) return n;
 
    // If second string is empty, the only option is to
    // remove all characters of first string
    if (n == 0) return m;
 
    // If last characters of two strings are same, ignore
    // last characters and get count for remaining strings.
    if (str1[m-1] == str2[n-1])
        return isKPalRec(str1, str2, m-1, n-1);
 
    // If last characters are not same,
    // 1. Remove last char from str1 and recur for m-1 and n
    // 2. Remove last char from str2 and recur for m and n-1
    // Take minimum of above two operations
    return 1 + min(isKPalRec(str1, str2, m-1, n), // Remove from str1
                   isKPalRec(str1, str2, m, n-1)); // Remove from str2
}
 
// Returns true if str is k palindrome.
bool isKPal(string str, int k)
{
    string revStr = str;
    reverse(revStr.begin(), revStr.end());
    int len = str.length();
 
    return (isKPalRec(str, revStr, len, len) <= k*2);
}
 
// Driver program
int main()
{
    string str = "acdcb";
    int k = 2;
    isKPal(str, k)? cout << "Yes" : cout << "No";
    return 0;
}


Java
// A Naive recursive Java program
// to find if given string is
// K-Palindrome or not
class GFG
{
 
    // find if given string is
    // K-Palindrome or not
    static int isKPalRec(String str1,
            String str2, int m, int n)
    {
        // If first string is empty,
        // the only option is to remove
        // all characters of second string
        if (m == 0)
        {
            return n;
        }
 
        // If second string is empty,
        // the only option is to remove
        // all characters of first string
        if (n == 0)
        {
            return m;
        }
 
        // If last characters of two
        // strings are same, ignore
        // last characters and get
        // count for remaining strings.
        if (str1.charAt(m - 1) ==
            str2.charAt(n - 1))
        {
            return isKPalRec(str1, str2,
                            m - 1, n - 1);
        }
 
        // If last characters are not same,
        // 1. Remove last char from str1 and
        // recur for m-1 and n
        // 2. Remove last char from str2 and
        // recur for m and n-1
        // Take minimum of above two operations
        return 1 + Math.min(isKPalRec(str1, str2, m - 1, n), // Remove from str1
                isKPalRec(str1, str2, m, n - 1)); // Remove from str2
    }
 
    // Returns true if str is k palindrome.
    static boolean isKPal(String str, int k)
    {
        String revStr = str;
        revStr = reverse(revStr);
        int len = str.length();
 
        return (isKPalRec(str, revStr, len, len) <= k * 2);
    }
 
    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.valueOf(temparray);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String str = "acdcb";
        int k = 2;
        if (isKPal(str, k))
        {
            System.out.println("Yes");
        }
        else
        {
            System.out.println("No");
        }
    }
}
 
// This code is contributed by Rajput-Ji


Python3
# A Naive recursive Python3
# code to find if given string
# is K-Palindrome or not
 
# Find if given string
# is K-Palindrome or not
def isKPalRec(str1, str2, m, n):
     
    # If first string is empty,
    # the only option is to remove
    # all characters of second string
    if not m: return n
 
    # If second string is empty,
    # the only option is to remove
    # all characters of first string
    if not n: return m
 
    # If last characters of two strings
    # are same, ignore last characters
    # and get count for remaining strings.
    if str1[m-1] == str2[n-1]:
        return isKPalRec(str1, str2, m-1, n-1)
 
    # If last characters are not same,
    # 1. Remove last char from str1 and recur for m-1 and n
    # 2. Remove last char from str2 and recur for m and n-1
    # Take minimum of above two operations
    res = 1 + min(isKPalRec(str1, str2, m-1, n),  # Remove from str1
                 (isKPalRec(str1, str2, m, n-1))) # Remove from str2
                  
    return res
 
# Returns true if str is k palindrome.
def isKPal(string, k):
    revStr = string[::-1]
    l = len(string)
 
    return (isKPalRec(string, revStr, l, l) <= k * 2)
 
 
# Driver program
string = "acdcb"
k = 2
 
print("Yes" if isKPal(string, k) else "No")
 
 
# This code is contributed by Ansu Kumari.


C#
// A Naive recursive C# program
// to find if given string is
// K-Palindrome or not
using System;
 
class GFG
{
 
    // find if given string is
    // K-Palindrome or not
    static int isKPalRec(String str1,
            String str2, int m, int n)
    {
        // If first string is empty,
        // the only option is to remove
        // all characters of second string
        if (m == 0)
        {
            return n;
        }
 
        // If second string is empty,
        // the only option is to remove
        // all characters of first string
        if (n == 0)
        {
            return m;
        }
 
        // If last characters of two
        // strings are same, ignore
        // last characters and get
        // count for remaining strings.
        if (str1[m - 1] ==
            str2[n - 1])
        {
            return isKPalRec(str1, str2,
                            m - 1, n - 1);
        }
 
        // If last characters are not same,
        // 1. Remove last char from str1 and
        // recur for m-1 and n
        // 2. Remove last char from str2 and
        // recur for m and n-1
        // Take minimum of above two operations
        return 1 + Math.Min(isKPalRec(str1, str2, m - 1, n), // Remove from str1
                isKPalRec(str1, str2, m, n - 1)); // Remove from str2
    }
 
    // Returns true if str is k palindrome.
    static bool isKPal(String str, int k)
    {
        String revStr = str;
        revStr = reverse(revStr);
        int len = str.Length;
 
        return (isKPalRec(str, revStr, len, len) <= k * 2);
    }
 
    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 = "acdcb";
        int k = 2;
        if (isKPal(str, k))
        {
            Console.WriteLine("Yes");
        }
        else
        {
            Console.WriteLine("No");
        }
    }
}
 
// This code is contributed by 29AjayKumar


C++
// C++ program to find if given string is K-Palindrome or not
#include 
using namespace std;
 
// find if given string is K-Palindrome or not
int isKPalDP(string str1, string str2, int m, int n)
{
    // Create a table to store results of subproblems
    int dp[m + 1][n + 1];
 
    // Fill dp[][] in bottom up manner
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            // If first string is empty, only option is to
            // remove all characters of second string
            if (i == 0)
                dp[i][j] = j; // Min. operations = j
 
            // If second string is empty, only option is to
            // remove all characters of first string
            else if (j == 0)
                dp[i][j] = i; // Min. operations = i
 
            // If last characters are same, ignore last character
            // and recur for remaining string
            else if (str1[i - 1] == str2[j - 1])
                dp[i][j] = dp[i - 1][j - 1];
 
            // If last character are different, remove it
            // and find minimum
            else
             dp[i][j] = 1 + min(dp[i - 1][j], // Remove from str1
                             dp[i][j - 1]); // Remove from str2
        }
    }
 
    return dp[m][n];
}
 
// Returns true if str is k palindrome.
bool isKPal(string str, int k)
{
    string revStr = str;
    reverse(revStr.begin(), revStr.end());
    int len = str.length();
 
    return (isKPalDP(str, revStr, len, len) <= k*2);
}
 
// Driver program
int main()
{
    string str = "acdcb";
    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
{
 
    // find if given string is
    // K-Palindrome or not
    static int isKPalDP(String str1,
            String str2, int m, int n)
    {
         
        // Create a table to store
        // results of subproblems
        int dp[][] = new int[m + 1][n + 1];
 
        // Fill dp[][] in bottom up manner
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                 
                // If first string is empty,
                // only option is to remove all
                // characters of second string
                if (i == 0)
                {
                    // Min. operations = j
                    dp[i][j] = j;
                }
                 
                // If second string is empty,
                // only option is to remove all
                // characters of first string
                else if (j == 0)
                {
                    // Min. operations = i
                    dp[i][j] = i;
                }
                 
                // If last characters are same,
                // ignore last character and
                // recur for remaining string
                else if (str1.charAt(i - 1) ==
                        str2.charAt(j - 1))
                {
                    dp[i][j] = dp[i - 1][j - 1];
                }
                 
                // If last character are different,
                //  remove it and find minimum
                else
                {
                    // Remove from str1
                    // Remove from str2
                    dp[i][j] = 1 + Math.min(dp[i - 1][j],
                            dp[i][j - 1]);
                }
            }
        }
        return dp[m][n];
    }
 
    // Returns true if str is k palindrome.
    static boolean isKPal(String str, int k)
    {
        String revStr = str;
        revStr = reverse(revStr);
        int len = str.length();
 
        return (isKPalDP(str, revStr,
                len, len) <= k * 2);
    }
 
    static String reverse(String str)
    {
        StringBuilder sb = new StringBuilder(str);
        sb.reverse();
        return sb.toString();
    }
     
    // Driver program
    public static void main(String[] args)
    {
        String str = "acdcb";
        int k = 2;
        if (isKPal(str, k))
        {
            System.out.println("Yes");
        }
        else
        {
            System.out.println("No");
        }
    }
}
 
// This code is contributed by
// PrinciRaj1992


Python3
# Python program to find if given
# string is K-Palindrome or not
 
# Find if given string is
# K-Palindrome or not
def isKPalDP(str1, str2, m, n):
     
    # Create a table to store
    # results of subproblems
    dp = [[0] * (n + 1) for _ in range(m + 1)]
 
    # Fill dp[][] in bottom up manner
    for i in range(m + 1):
         
        for j in range(n + 1):
             
            # If first string is empty,
            # only option is to remove
            # all characters of second string
            if not i :
                dp[i][j] = j    # Min. operations = j
 
            # If second string is empty,
            # only option is to remove
            # all characters of first string
            elif not j :
                dp[i][j] = i    # Min. operations = i
 
            # If last characters are same,
            # ignore last character and
            # recur for remaining string
            elif (str1[i - 1] == str2[j - 1]):
                dp[i][j] = dp[i - 1][j - 1]
 
            # If last character are different,
            # remove it and find minimum
            else:
                dp[i][j] = 1 + min(dp[i - 1][j],  # Remove from str1
                                  (dp[i][j - 1])) # Remove from str2
 
    return dp[m][n]
 
# Returns true if str
# is k palindrome.
def isKPal(string, k):
     
    revStr = string[::-1]
    l = len(string)
     
    return (isKPalDP(string, revStr, l, l) <= k * 2)
 
 
# Driver program
string = "acdcb"
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 {
     
    // find if given string is
    // K-Palindrome or not
    static int isKPalDP(string str1, 
            string str2, int m, int n) 
    {
           
        // Create a table to store 
        // results of subproblems
        int[,] dp = new int[m + 1, n + 1];
   
        // Fill dp[][] in bottom up manner
        for (int i = 0; i <= m; i++) 
        {
            for (int j = 0; j <= n; j++) 
            {
                   
                // If first string is empty,
                // only option is to remove all
                // characters of second string
                if (i == 0) 
                {
                    // Min. operations = j
                    dp[i, j] = j; 
                } 
                   
                // If second string is empty, 
                // only option is to remove all
                // characters of first string
                else if (j == 0) 
                {
                    // Min. operations = i
                    dp[i, j] = i; 
                } 
                   
                // If last characters are same, 
                // ignore last character and
                // recur for remaining string
                else if (str1[i - 1] == str2[j - 1]) 
                {
                    dp[i, j] = dp[i - 1, j - 1];
                } 
                   
                // If last character are different,
                //  remove it and find minimum
                else
                {
                    // Remove from str1
                    // Remove from str2
                    dp[i, j] = 1 + Math.Min(dp[i - 1, j], dp[i, j - 1]); 
                }
            }
        }
        return dp[m, n];
    }
     
    // Returns true if str is k palindrome.
    static bool isKPal(string str, int k)
    {
        string revStr = str;
        revStr = reverse(revStr);
        int len = str.Length;
        return (isKPalDP(str, revStr, len, len) <= k * 2);
    }
     
    static string reverse(string str)
    {
        char[] sb = str.ToCharArray();
        Array.Reverse(sb);
        return new string(sb);
    }
     
    static void Main() {
        string str = "acdcb";
        int k = 2;
        if (isKPal(str, k)) 
        {
            Console.WriteLine("Yes");
        } 
        else
        {
            Console.WriteLine("No");
        }
    }
}
 
// This code is contributed by divyesh072019


输出 :

Yes

上述解决方案的时间复杂度是指数级的。在最坏的情况下,我们最终可能会执行 O(2 n ) 次操作。最坏的情况是字符串包含所有不同的字符。
这个问题具有动态规划问题的两个属性(见this和this)。与其他典型的动态规划 (DP) 问题一样,可以通过构造一个存储子问题结果的临时数组来避免对相同子问题的重新计算。
以下是上述递归方法的自底向上实现:

C++

// C++ program to find if given string is K-Palindrome or not
#include 
using namespace std;
 
// find if given string is K-Palindrome or not
int isKPalDP(string str1, string str2, int m, int n)
{
    // Create a table to store results of subproblems
    int dp[m + 1][n + 1];
 
    // Fill dp[][] in bottom up manner
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            // If first string is empty, only option is to
            // remove all characters of second string
            if (i == 0)
                dp[i][j] = j; // Min. operations = j
 
            // If second string is empty, only option is to
            // remove all characters of first string
            else if (j == 0)
                dp[i][j] = i; // Min. operations = i
 
            // If last characters are same, ignore last character
            // and recur for remaining string
            else if (str1[i - 1] == str2[j - 1])
                dp[i][j] = dp[i - 1][j - 1];
 
            // If last character are different, remove it
            // and find minimum
            else
             dp[i][j] = 1 + min(dp[i - 1][j], // Remove from str1
                             dp[i][j - 1]); // Remove from str2
        }
    }
 
    return dp[m][n];
}
 
// Returns true if str is k palindrome.
bool isKPal(string str, int k)
{
    string revStr = str;
    reverse(revStr.begin(), revStr.end());
    int len = str.length();
 
    return (isKPalDP(str, revStr, len, len) <= k*2);
}
 
// Driver program
int main()
{
    string str = "acdcb";
    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
{
 
    // find if given string is
    // K-Palindrome or not
    static int isKPalDP(String str1,
            String str2, int m, int n)
    {
         
        // Create a table to store
        // results of subproblems
        int dp[][] = new int[m + 1][n + 1];
 
        // Fill dp[][] in bottom up manner
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                 
                // If first string is empty,
                // only option is to remove all
                // characters of second string
                if (i == 0)
                {
                    // Min. operations = j
                    dp[i][j] = j;
                }
                 
                // If second string is empty,
                // only option is to remove all
                // characters of first string
                else if (j == 0)
                {
                    // Min. operations = i
                    dp[i][j] = i;
                }
                 
                // If last characters are same,
                // ignore last character and
                // recur for remaining string
                else if (str1.charAt(i - 1) ==
                        str2.charAt(j - 1))
                {
                    dp[i][j] = dp[i - 1][j - 1];
                }
                 
                // If last character are different,
                //  remove it and find minimum
                else
                {
                    // Remove from str1
                    // Remove from str2
                    dp[i][j] = 1 + Math.min(dp[i - 1][j],
                            dp[i][j - 1]);
                }
            }
        }
        return dp[m][n];
    }
 
    // Returns true if str is k palindrome.
    static boolean isKPal(String str, int k)
    {
        String revStr = str;
        revStr = reverse(revStr);
        int len = str.length();
 
        return (isKPalDP(str, revStr,
                len, len) <= k * 2);
    }
 
    static String reverse(String str)
    {
        StringBuilder sb = new StringBuilder(str);
        sb.reverse();
        return sb.toString();
    }
     
    // Driver program
    public static void main(String[] args)
    {
        String str = "acdcb";
        int k = 2;
        if (isKPal(str, k))
        {
            System.out.println("Yes");
        }
        else
        {
            System.out.println("No");
        }
    }
}
 
// This code is contributed by
// PrinciRaj1992

蟒蛇3

# Python program to find if given
# string is K-Palindrome or not
 
# Find if given string is
# K-Palindrome or not
def isKPalDP(str1, str2, m, n):
     
    # Create a table to store
    # results of subproblems
    dp = [[0] * (n + 1) for _ in range(m + 1)]
 
    # Fill dp[][] in bottom up manner
    for i in range(m + 1):
         
        for j in range(n + 1):
             
            # If first string is empty,
            # only option is to remove
            # all characters of second string
            if not i :
                dp[i][j] = j    # Min. operations = j
 
            # If second string is empty,
            # only option is to remove
            # all characters of first string
            elif not j :
                dp[i][j] = i    # Min. operations = i
 
            # If last characters are same,
            # ignore last character and
            # recur for remaining string
            elif (str1[i - 1] == str2[j - 1]):
                dp[i][j] = dp[i - 1][j - 1]
 
            # If last character are different,
            # remove it and find minimum
            else:
                dp[i][j] = 1 + min(dp[i - 1][j],  # Remove from str1
                                  (dp[i][j - 1])) # Remove from str2
 
    return dp[m][n]
 
# Returns true if str
# is k palindrome.
def isKPal(string, k):
     
    revStr = string[::-1]
    l = len(string)
     
    return (isKPalDP(string, revStr, l, l) <= k * 2)
 
 
# Driver program
string = "acdcb"
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 {
     
    // find if given string is
    // K-Palindrome or not
    static int isKPalDP(string str1, 
            string str2, int m, int n) 
    {
           
        // Create a table to store 
        // results of subproblems
        int[,] dp = new int[m + 1, n + 1];
   
        // Fill dp[][] in bottom up manner
        for (int i = 0; i <= m; i++) 
        {
            for (int j = 0; j <= n; j++) 
            {
                   
                // If first string is empty,
                // only option is to remove all
                // characters of second string
                if (i == 0) 
                {
                    // Min. operations = j
                    dp[i, j] = j; 
                } 
                   
                // If second string is empty, 
                // only option is to remove all
                // characters of first string
                else if (j == 0) 
                {
                    // Min. operations = i
                    dp[i, j] = i; 
                } 
                   
                // If last characters are same, 
                // ignore last character and
                // recur for remaining string
                else if (str1[i - 1] == str2[j - 1]) 
                {
                    dp[i, j] = dp[i - 1, j - 1];
                } 
                   
                // If last character are different,
                //  remove it and find minimum
                else
                {
                    // Remove from str1
                    // Remove from str2
                    dp[i, j] = 1 + Math.Min(dp[i - 1, j], dp[i, j - 1]); 
                }
            }
        }
        return dp[m, n];
    }
     
    // Returns true if str is k palindrome.
    static bool isKPal(string str, int k)
    {
        string revStr = str;
        revStr = reverse(revStr);
        int len = str.Length;
        return (isKPalDP(str, revStr, len, len) <= k * 2);
    }
     
    static string reverse(string str)
    {
        char[] sb = str.ToCharArray();
        Array.Reverse(sb);
        return new string(sb);
    }
     
    static void Main() {
        string str = "acdcb";
        int k = 2;
        if (isKPal(str, k)) 
        {
            Console.WriteLine("Yes");
        } 
        else
        {
            Console.WriteLine("No");
        }
    }
}
 
// This code is contributed by divyesh072019

输出 :

Yes

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