String is K-Palindrome or Not

Last Updated : 11 May, 2026

Given a string s, find out if the string is k-Palindrome or not. A k-palindrome string transforms into a palindrome on removing at most k characters from it.
Examples : 

Input: s = "abcdecba", k = 1
Output: true
Explanation: String can become palindrome by removing 1 character i.e. either d or e.

Input: s = "abcdeca", k = 2
Output: true
Explanation: Can become palindrome by removing 2 characters b and e.

Input: s= "acdcb", k = 1
Output: false
Explanation: String can not become palindrome by removing only one character.

Try It Yourself
redirect icon

[Naive Approach] Edit Distance Recursion and Reverse – O(2 ^ n) Time and O(n) Space

If we carefully analyze the problem, it is basically a variation of Edit Distance. We can modify the Edit Distance problem to consider the given string and its reverse as input and the only operation allowed is deletion. To form a palindrome, the same character has to deleted from both s and its reverse. Therefore, for a string to be k-palindrome, total deletions <= 2*k should hold true.

  • If the last characters of the two strings are same, we ignore last characters and get count for remaining strings. So we recur for lengths m-1 and n-1 where m is length of s1 and n is length of s2.
  • If the last characters are not same, remove last char from s1 and recur for m-1 and n. Then remove last char from s2 and recur for m and n-1. We take the minimum of two operations and add 1 to it.
C++
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

// find if given string is K-Palindrome or not
int isKPalRec(string s1, string s2, 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 (s1[m-1] == s2[n-1])
        return isKPalRec(s1, s2, m-1, n-1);

    // If last characters are not same,
    // 1. Remove last char from s1 and recur for m-1 and n
    // 2. Remove last char from s2 and recur for m and n-1
    // Take minimum of above two operations
    return 1 + min(isKPalRec(s1, s2, m-1, n), // Remove from s1
                   isKPalRec(s1, s2, m, n-1)); // Remove from s2
}

// Returns true if s is k palindrome.
bool kPalindrome(string &s, int k)
{
    string s1 = s;
    reverse(s1.begin(), s1.end());

    int n = s.length();

    return (isKPalRec(s, s1, n, n) <= k * 2);
}

// Driver program
int main()
{
    string s = "acdcb";
    int k = 2;

    kPalindrome(s, k) ? cout << "True" : cout << "False";

    return 0;
}
Java
import java.util.*;

class GFG {

    // find if given string is K-Palindrome or not
    static int isKPalRec(String s1, String s2, 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 (s1.charAt(m - 1) == s2.charAt(n - 1))
            return isKPalRec(s1, s2, m - 1, n - 1);

        // If last characters are not same,
        // 1. Remove last char from s1 and recur for m-1 and n
        // 2. Remove last char from s2 and recur for m and n-1
        // Take minimum of above two operations
        return 1 + Math.min(isKPalRec(s1, s2, m - 1, n), // Remove from s1
                            isKPalRec(s1, s2, m, n - 1)); // Remove from s2
    }

    // Returns true if s is k palindrome.
    static boolean kPalindrome(String s, int k)
    {
        String s1 = new StringBuilder(s).reverse().toString();

        int n = s.length();

        return (isKPalRec(s, s1, n, n) <= k * 2);
    }

    // Driver program
    public static void main(String[] args)
    {
        String s = "acdcb";
        int k = 2;

        System.out.println(kPalindrome(s, k) ? "Yes" : "No");
    }
}
Python
# find if given string is K-Palindrome or not
def isKPalRec(s1, s2, m, 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 s1[m - 1] == s2[n - 1]:
        return isKPalRec(s1, s2, m - 1, n - 1)

    # If last characters are not same,
    # 1. Remove last char from s1 and recur for m-1 and n
    # 2. Remove last char from s2 and recur for m and n-1
    # Take minimum of above two operations
    return 1 + min(isKPalRec(s1, s2, m - 1, n),  # Remove from s1
                   isKPalRec(s1, s2, m, n - 1))  # Remove from s2


# Returns true if s is k palindrome.
def kPalindrome(s, k):

    s1 = s[::-1]

    n = len(s)

    return isKPalRec(s, s1, n, n) <= k * 2


# Driver program
s = "acdcb"
k = 2

print("Yes" if kPalindrome(s, k) else "No")
C#
using System;

class GFG {

    // find if given string is K-Palindrome or not
    static int isKPalRec(string s1, string s2, 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 (s1[m - 1] == s2[n - 1])
            return isKPalRec(s1, s2, m - 1, n - 1);

        // If last characters are not same,
        // 1. Remove last char from s1 and recur for m-1 and n
        // 2. Remove last char from s2 and recur for m and n-1
        // Take minimum of above two operations
        return 1 + Math.Min(isKPalRec(s1, s2, m - 1, n), // Remove from s1
                            isKPalRec(s1, s2, m, n - 1)); // Remove from s2
    }

    // Returns true if s is k palindrome.
    static bool kPalindrome(string s, int k)
    {
        char[] arr = s.ToCharArray();
        Array.Reverse(arr);

        string s1 = new string(arr);

        int n = s.Length;

        return (isKPalRec(s, s1, n, n) <= k * 2);
    }

    // Driver program
    static void Main()
    {
        string s = "acdcb";
        int k = 2;

        Console.WriteLine(kPalindrome(s, k) ? "Yes" : "No");
    }
}
JavaScript
// find if given string is K-Palindrome or not
function isKPalRec(s1, s2, m, 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 (s1[m - 1] == s2[n - 1])
        return isKPalRec(s1, s2, m - 1, n - 1);

    // If last characters are not same,
    // 1. Remove last char from s1 and recur for m-1 and n
    // 2. Remove last char from s2 and recur for m and n-1
    // Take minimum of above two operations
    return 1 + Math.min(isKPalRec(s1, s2, m - 1, n), // Remove from s1
                        isKPalRec(s1, s2, m, n - 1)); // Remove from s2
}

// Returns true if s is k palindrome.
function kPalindrome(s, k)
{
    let s1 = s.split('').reverse().join('');

    let n = s.length;

    return (isKPalRec(s, s1, n, n) <= k * 2);
}

// Driver program
let s = "acdcb";
let k = 2;

console.log(kPalindrome(s, k) ? "Yes" : "No");

Output
True

[Expected Approach 1] Edit Distance Bottom Up and Reverse – O(n²) Time and O(n²) Space

We mainly optimize the above recursive solution using a dp table of size (m+1)x(n+1) where dp[i][j] represents total deletions to match prefixes of lengths i and j. At the end, we return return true if dp[m][n] <= 2*k.

  • Reverse the original string.
  • Build a DP table where each cell dp[i][j] stores minimum deletions required to match prefixes of lengths i and j.
  • If characters match, move diagonally; otherwise take minimum deletion operation
  • Check if final deletions required are less than or equal to 2 * k


C++
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

// find if given string is K-Palindrome or not
int isKPalDP(string s1, string s2, 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 (s1[i - 1] == s2[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 s1
                                   dp[i][j - 1]); // Remove from s2
        }
    }

    return dp[m][n];
}

// Returns true if s is k palindrome.
bool kPalindrome(string &s, int k)
{
    string s1 = s;

    reverse(s1.begin(), s1.end());

    int n = s.length();

    return (isKPalDP(s, s1, n, n) <= k * 2);
}

// Driver program
int main()
{
    string s = "acdcb";
    int k = 2;

    kPalindrome(s, k) ? cout << "True" : cout << "False";

    return 0;
}
Java
import java.util.*;

class GFG {

    // find if given string is K-Palindrome or not
    static int isKPalDP(String s1, String s2, 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)
                    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 (s1.charAt(i - 1) == s2.charAt(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 + Math.min(dp[i - 1][j], // Remove from s1
                                            dp[i][j - 1]); // Remove from s2
            }
        }

        return dp[m][n];
    }

    // Returns true if s is k palindrome.
    static boolean kPalindrome(String s, int k)
    {
        String s1 = s;

        s1 = new StringBuilder(s1).reverse().toString();

        int n = s.length();

        return (isKPalDP(s, s1, n, n) <= k * 2);
    }

    // Driver program
    public static void main(String[] args)
    {
        String s = "acdcb";
        int k = 2;

        System.out.println(kPalindrome(s, k) ? "True" : "False");
    }
}
Python
# find if given string is K-Palindrome or not
def isKPalDP(s1, s2, m, n):

    # Create a table to store results of subproblems
    dp = [[0 for j in range(n + 1)] for i 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 i == 0:
                dp[i][j] = j  # Min. operations = j

            # If second string is empty, only option is to
            # remove all characters of first string
            elif j == 0:
                dp[i][j] = i  # Min. operations = i

            # If last characters are same, ignore last character
            # and recur for remaining string
            elif s1[i - 1] == s2[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 s1
                                   dp[i][j - 1])  # Remove from s2

    return dp[m][n]


# Returns true if s is k palindrome.
def kPalindrome(s, k):

    s1 = s

    s1 = s1[::-1]

    n = len(s)

    return isKPalDP(s, s1, n, n) <= k * 2


# Driver program
s = "acdcb"
k = 2

print("True" if kPalindrome(s, k) else "False")
C#
using System;

class GFG {

    // find if given string is K-Palindrome or not
    static int isKPalDP(string s1, string s2, 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)
                    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 (s1[i - 1] == s2[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 + Math.Min(dp[i - 1, j], // Remove from s1
                                            dp[i, j - 1]); // Remove from s2
            }
        }

        return dp[m, n];
    }

    // Returns true if s is k palindrome.
    static bool kPalindrome(string s, int k)
    {
        string s1 = s;

        char[] arr = s1.ToCharArray();

        Array.Reverse(arr);

        s1 = new string(arr);

        int n = s.Length;

        return (isKPalDP(s, s1, n, n) <= k * 2);
    }

    // Driver program
    static void Main()
    {
        string s = "acdcb";
        int k = 2;

        Console.WriteLine(kPalindrome(s, k) ? "True" : "False");
    }
}
JavaScript
// find if given string is K-Palindrome or not
function isKPalDP(s1, s2, m, n)
{
    // Create a table to store results of subproblems
    let dp = Array.from({ length: m + 1 }, () =>
        Array(n + 1).fill(0)
    );

    // Fill dp[][] in bottom up manner
    for (let i = 0; i <= m; i++)
    {
        for (let 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 (s1[i - 1] == s2[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 + Math.min(dp[i - 1][j], // Remove from s1
                                        dp[i][j - 1]); // Remove from s2
        }
    }

    return dp[m][n];
}

// Returns true if s is k palindrome.
function kPalindrome(s, k)
{
    let s1 = s;

    s1 = s1.split('').reverse().join('');

    let n = s.length;

    return (isKPalDP(s, s1, n, n) <= k * 2);
}

// Driver program
let s = "acdcb";
let k = 2;

console.log(kPalindrome(s, k) ? "True" : "False");

Output
True

[Efficient Approach] Using Longest Palindromic Subsequence (LPS) – O(n²) Time and O(n²) Space

The idea to find Longest Palindromic Subsequence (LPS) and subtract its length from total string length to find the number of deletions. We compute LPS using LCS between the string and its reverse. If the number of characters not included in the LPS is at most k, then the string can be converted into a palindrome by removing at most k characters. Thus, we only need to check whether n - LPS <= k.

  • Reverse the original string and compute LCS between both strings
  • Use dynamic programming to build the LCS table
  • The LCS length represents the longest palindromic subsequence
  • If n - LPS <= k, return true otherwise false


C++
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

/* Returns length of LCS for s1 and s2 */
int lcs(string s1, string s2, int m, int n)
{
    int dp[m + 1][n + 1];

    /* Following steps build dp[m+1][n+1] in bottom up
        fashion. Note that dp[i][j] contains length of
        LCS of a1 and s2 */
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            if (i == 0 || j == 0)
                dp[i][j] = 0;

            else if (s1[i - 1] == s2[j - 1])
                dp[i][j] = dp[i - 1][j - 1] + 1;

            else
                dp[i][j] = max(dp[i - 1][j],
                               dp[i][j - 1]);
        }
    }

    // dp[m][n] contains length of LCS for s1 and s2
    return dp[m][n];
}

// find if given string is K-Palindrome or not
bool kPalindrome(string &s, int k)
{
    int n = s.length();

    // Find reverse of string
    string s1 = s;

    reverse(s1.begin(), s1.end());

    // find longest palindromic subsequence of
    // given string
    int lps = lcs(s, s1, 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 s = "abcdeca";
    int k = 2;

    kPalindrome(s, k) ? cout << "True" : cout << "False";

    return 0;
}
Java
import java.util.*;

class GFG {

    /* Returns length of LCS for s1 and s2 */
    static int lcs(String s1, String s2, int m, int n)
    {
        int[][] dp = new int[m + 1][n + 1];

        /* Following steps build dp[m+1][n+1] in bottom up
            fashion. Note that dp[i][j] contains length of
            LCS of a1 and s2 */
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                if (i == 0 || j == 0)
                    dp[i][j] = 0;

                else if (s1.charAt(i - 1) == s2.charAt(j - 1))
                    dp[i][j] = dp[i - 1][j - 1] + 1;

                else
                    dp[i][j] = Math.max(dp[i - 1][j],
                                        dp[i][j - 1]);
            }
        }

        // dp[m][n] contains length of LCS for s1 and s2
        return dp[m][n];
    }

    // find if given string is K-Palindrome or not
    static boolean kPalindrome(String s, int k)
    {
        int n = s.length();

        // Find reverse of string
        String s1 = s;

        s1 = new StringBuilder(s1).reverse().toString();

        // find longest palindromic subsequence of
        // given string
        int lps = lcs(s, s1, 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
    public static void main(String[] args)
    {
        String s = "abcdeca";
        int k = 2;

        System.out.println(kPalindrome(s, k) ? "True" : "False");
    }
}
Python
# Returns length of LCS for s1 and s2
def lcs(s1, s2, m, n):

    dp = [[0 for j in range(n + 1)] for i in range(m + 1)]

    # Following steps build dp[m+1][n+1] in bottom up
    # fashion. Note that dp[i][j] contains length of
    # LCS of a1 and s2
    for i in range(m + 1):

        for j in range(n + 1):

            if i == 0 or j == 0:
                dp[i][j] = 0

            elif s1[i - 1] == s2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1

            else:
                dp[i][j] = max(dp[i - 1][j],
                               dp[i][j - 1])

    # dp[m][n] contains length of LCS for s1 and s2
    return dp[m][n]


# find if given string is K-Palindrome or not
def kPalindrome(s, k):

    n = len(s)

    # Find reverse of string
    s1 = s

    s1 = s1[::-1]

    # find longest palindromic subsequence of
    # given string
    lps = lcs(s, s1, 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
s = "abcdeca"
k = 2

print("True" if kPalindrome(s, k) else "False")
C#
using System;

class GFG {

    /* Returns length of LCS for s1 and s2 */
    static int lcs(string s1, string s2, int m, int n)
    {
        int[,] dp = new int[m + 1, n + 1];

        /* Following steps build dp[m+1][n+1] in bottom up
            fashion. Note that dp[i][j] contains length of
            LCS of a1 and s2 */
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                if (i == 0 || j == 0)
                    dp[i, j] = 0;

                else if (s1[i - 1] == s2[j - 1])
                    dp[i, j] = dp[i - 1, j - 1] + 1;

                else
                    dp[i, j] = Math.Max(dp[i - 1, j],
                                        dp[i, j - 1]);
            }
        }

        // dp[m][n] contains length of LCS for s1 and s2
        return dp[m, n];
    }

    // find if given string is K-Palindrome or not
    static bool kPalindrome(string s, int k)
    {
        int n = s.Length;

        // Find reverse of string
        string s1 = s;

        char[] arr = s1.ToCharArray();

        Array.Reverse(arr);

        s1 = new string(arr);

        // find longest palindromic subsequence of
        // given string
        int lps = lcs(s, s1, 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
    static void Main()
    {
        string s = "abcdeca";
        int k = 2;

        Console.WriteLine(kPalindrome(s, k) ? "True" : "False");
    }
}
JavaScript
/* Returns length of LCS for s1 and s2 */
function lcs(s1, s2, m, n)
{
    let dp = Array.from({ length: m + 1 }, () =>
        Array(n + 1).fill(0)
    );

    /* Following steps build dp[m+1][n+1] in bottom up
        fashion. Note that dp[i][j] contains length of
        LCS of a1 and s2 */
    for (let i = 0; i <= m; i++)
    {
        for (let j = 0; j <= n; j++)
        {
            if (i == 0 || j == 0)
                dp[i][j] = 0;

            else if (s1[i - 1] == s2[j - 1])
                dp[i][j] = dp[i - 1][j - 1] + 1;

            else
                dp[i][j] = Math.max(dp[i - 1][j],
                                    dp[i][j - 1]);
        }
    }

    // dp[m][n] contains length of LCS for s1 and s2
    return dp[m][n];
}

// find if given string is K-Palindrome or not
function kPalindrome(s, k)
{
    let n = s.length;

    // Find reverse of string
    let s1 = s;

    s1 = s1.split('').reverse().join('');

    // find longest palindromic subsequence of
    // given string
    let lps = lcs(s, s1, 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
let s = "abcdeca";
let k = 2;

console.log(kPalindrome(s, k) ? "True" : "False");

Output
True
Comment