Given a string s, you can insert any character anywhere in the string with each operation.
Please return the minimum number of operations to make s a palindrome.
A "palindromic string" is a string that reads the same forward and backward.
Example 1:
Input: s = "zzazz"
Output: 0
Explanation: The string "zzazz" is already a palindrome, so no insertion is required.
Example 2:
Input: s = "mbadm"
Output: 2
Explanation: String can be changed to "mbdadbm" or "mdbabdm".
Example 3:
Input: s = "leetcode"
Output: 5
Explanation: The string becomes "leetcodocteel" after inserting 5 characters.
Example 4:
Input: s = "g"
Output: 0
Example 5:
input: s = "no"
output: 1
hint:
1 <= s.length <= 500
All characters in s are lowercase letters.
Link: https://leetcode-cn.com/problems/minimum-insertion-steps-to-make-a-string-palindrome
Thought analysis:
Seeing the palindrome, it is obvious to consider the interval dp.
dp[i][len] represents the minimum number of insertions for a substring of length len starting from i to become a palindrome.
Let i be the left boundary of the interval and j be the right boundary of the interval. It can be found that if s[i] == s[j], only the minimum number of insertions of the substring of [i+1, j-1] needs to be considered. So dp[i][len] = dp[i+1][len-2] (s[i] == s[j])
When s[i] != s[j], there are two decisions: Inserts one character to the left of the left border and one character to the right of the right border.
Take "mbadm" as an example:
First, s[0] == s[4], only need to consider "bad" of [1,3].
For "bad", if you insert on the left side of the left boundary, you can get "dbad" . At this time we only need to consider the "ba" case.
So dp[i][len] = dp[i][len-1].
If you insert to the right of the right boundary, you can get "badb". At this time, we only need to consider the case of "ad".
Therefore dp[i][len] = dp[i+1][len-1].
Take the minimum value for the above two decisions.
class Solution {
public:
int minInsertions(string s) {
int n = s.length();
int dp[n+2][n+2];
for(int i = 0;i < n;i++)
{
dp[i][1] = 0;
if(i < n-1 && s[i] == s[i+1]) dp[i][2] = 0;
else dp[i][2] = 1;
}
for(int len = 3;len <= n;len++)
{
for(int i = 0;i <= n-len;i++)
{
int j = i+len-1;
if(s[i] == s[j]) dp[i][len] = dp[i+1][len-2];
else dp[i][len] = min(dp[i+1][len-1]+1, dp[i][len-1]+1);
}
}
return dp[0][n];
}
};