Problem 4 Valid Palindrome III
```java
/*
Clarification:
- check if you need to remove how many character to make it is a isValidPalindrome
Assumption:
- valid?
High Level
- Method 1: check the inverse string , if we can find the maximum
==> longest common subsequence
==> 什么情况下, 我就没有办法通过至多k次操作变成回文?不common的部分多于k个
- Method 2: check the interval between i, j , how many move we need for
Middle Level
Method 1.0:
- dp mean? dp[i][j] represents longest common sequence,
ends with the first seq ith, including ith index
ends with the second seq jth, including jth index
- basic case: dp[0][0] = 0;
- induction rule:
- dp[i][j] = max(dp[i-1][j-1] + 1, dp[i-1][j], dp[i][j-1]), if s.charAt(i -1) = sRev.charAt(j-1),
- dp[i][j] = max(dp[i-1][j-1] , dp[i-1][j], dp[i][j-1]), if s.charAt(i-1)!= sRev.charAt(j-1)
- filling
- from up to down, from left to right
- return result
- dp[s.length][s.length] >= s.length()-k?
Method 1.1:
- preDial =?
- top = dp[i] //这相当于上一行的头顶那个element
- if text1.charAt(i) == text2.charAt(j), dp[i] = max(dp[i-1], preDial + 1, top);
- else: dp[i] = max(dp[i-1], preDial, top)
- preDial = top, top = dp[i] //preDial往右移动一格,top也往右移动一格
Method 2:
- dp means? dp[i][j] represents the minimum remove elements
- base case
- induction rule: i < j
dp[i][j] =
j - i == 0? dp[i][j] = 0
j - i == 1? dp[i][j] = s.charAt(i) ==s.charAt(j) ? 0: 1;
j - i == others
dp[i][j] = s.charAt(i) == s.charAt(j) ?
Math.min(dp[i+1][j-1], Math.min(dp[i+1][j] + 1, dp[i][j-1] + 1)) : Math.min(dp[i+1][j-1] + 2, Math.min(dp[i][j-1] +1, dp[i+1][j] + 1));
// dp[i+1][j-1] : Math.min(dp[i][j-1] + 1, dp[i+1][j] + 1);
- filling order
- from bottom to top
- from left to right?
- (0,0) (0,1) (1,1)
- (1,1), (1,2)
- (2,2)
- filling (2,2), (1,1), (1,2),....
- return dp(0, s.size - 1) < k?
- TC(n^2), SC(n^2)
Comment:
- method 1: 你reverse以后,如果不match说明要换,,所以要找的是最长的common sequence,not a
- method 2:
Cost: 45mins + 15mins + 60mins + 30mins
*/
class Solution {
public boolean isValidPalindrome(String s, int k) {
// sanity check
// initial
int size = s.length();
int[][] dp = new int[size][size];
// dp and filling
for (int i = size - 1; i >= 0; i--) {
for (int j = i; j < size; j++) {
if (j - i == 0) {
dp[i][j] = 0;
}
else if (j - i == 1){
dp[i][j] = s.charAt(i) ==s.charAt(j) ? 0: 1;
} else {
dp[i][j] = Integer.MAX_VALUE;
dp[i][j] = s.charAt(i) ==s.charAt(j) ?
Math.min(dp[i+1][j-1], Math.min(dp[i+1][j] + 1, dp[i][j-1] + 1)) : Math.min(dp[i+1][j-1] + 2, Math.min(dp[i][j-1] +1, dp[i+1][j] + 1));
// dp[i+1][j-1] : Math.min(dp[i][j-1] + 1, dp[i+1][j] + 1);
}
}
}
// return value
return dp[0][size -1] <= k? true: false;
}
}
```
Last updated