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:
https://linzhongzl.wordpress.com/2013/11/25/k-palindrome/