Question:
A k-palindrome is a string which transforms into a palindrome on removing at most k characters.
Given a string S, and an interger K, print “YES” if S is a k-palindrome; otherwise print “NO”.
Constraints:
S has at most 20,000 characters.
0<=k<=30
Sample Test Case#1:
Input – abxa 1
Output – YES
Sample Test Case#2:
Input – abdxa 1
Output – No
one solution:
Let's say p[n] is a palindrom with lenght n. Let l will be begining, end e the end of a palindrom. Then we can see that:
1) p[l] == p[h], then we need to check p[l+1] == p[h – 1], i.e abcba, where p[l] == a == p[h]
2a) p[l] != p[h], then we need to check p[l+1],p[h] (we removed p[l])
2b) p[l] != p[h], then we need to check p[l], p[h-1], (we removed p[h])
bool isKPalindrom(string input, int k)
{
int answers[input.size() + 1][input.size() + 1];
int N = input.size();
for(int i = 0; i <= N; i++)
for(int j = 0; j <= N; j++)
answers[i][j] = 0;
for(int gap = 1; gap <= N; gap++)
{
int l = 1;
int h = l + gap;
for(; h <= N; l++, h++)
{
if(input[l-1] == input[h - 1])
answers[l][h] = answers[l+1][h-1];
else
answers[l][h] = 1 + min(answers[l+1][h], answers[l][h-1]);
}
}
return answers[1][N] <= k;
}
The complexity is O(n^2).
Another solution:
The question asks if we can transform the given string S into its reverse deleting at most K letters.
We could modify the traditional Edit-Distance algorithm, considering only deletions, and check if this edit distance is <= K. There is a problem though. S can have length = 20,000 and the Edit-Distance algorithm takes O(N^2). Which is too slow.
(From here on, I'll assume you're familiar with the Edit-Distance algorithm and its DP matrix)
However, we can take advantage of K. We are only interested *if* manage to delete K letters. This means that any position more than K positions away from the main diagonal is useless because its edit distance must exceed those K deletions.
Since we are comparing the string with its reverse, we will do at most K deletions and K insertions (to make them equal). Thus, we need to check if the ModifiedEditDistance is <= 2*K
Here's the code:
int kpalindrome(string &a, int k){
int asize = a.size();
string b = a;
reverse(b.begin(), b.end());
int bsize = asize;
vector<vector<int> > dp(asize+1, vector<int>(bsize+1, 1000));
for(int i = 0; i <= asize; i++){
dp[i][0] = i;
dp[0][i] = i;
}
for(int i = 1; i <= asize; i++){
for(int j = max(1, i-k); j <= min(bsize, i+k); j++){
if(a[i-1] == b[j-1]){
dp[i][j] = dp[i-1][j-1];
}
dp[i][j] = min(dp[i][j], dp[i-1][j]+1);
dp[i][j] = min(dp[i][j], dp[i][j-1]+1);
}
}
if(dp[asize][bsize]<= 2*k) return dp[asize][bsize];
else return -1;
}
int _tmain(int argc, _TCHAR* argv[])
{
string a = "abxa";
int ret = kpalindrome(a, 1);
cout<<ret<<endl;
return 0;
}
We only process 2*K+1 columns per row. So this algorithm works in O(N*K) which is fast enough.
From: