题目来源
题目描述
class Solution {
public:
string shortestPalindrome(string s) {
}
};
题目解析
要求返回一种添加的结果
利用表回溯即可
实现:
class Solution {
public:
std::string minInsertions(string str) {
if(str.size() < 2){
return str;
}
int N = str.size();
std::vector<std::vector<int>> dp(N, std::vector<int>(N, 0));
for (int i = 0; i < N - 1; ++i) {
dp[i][i + 1] = (str[i] == str[i + 1]) ? 0 : 1;
}
for (int i = N - 3; i >= 0; --i) {
for (int j = i + 2; j < N; ++j) {
dp[i][j] = std::min(dp[i][j - 1], dp[i + 1][j]) + 1;
if(str[i] == str[j]){
dp[i][j] = std::min(dp[i + 1][j - 1], dp[i][j]);
}
}
}
std::string ans(N + dp[0][N - 1], ' ');
int i = 0, j = N - 1;
int ansi = 0, ansj = ans.size() - 1;
while (i < j){
if((dp[i][j - 1] + 1) == dp[i][j]){
ans[ansi++] = str[j];
ans[ansj--] = str[j--];
}else if((dp[i + 1][j] + 1) == dp[i][j]){
ans[ansi++] = str[i];
ans[ansj--] = str[i++];
}else{
ans[ansi++] = str[i++];
ans[ansj--] = str[j--];
}
}
if(i == j){
ans[ansi] = str[i];
}
return ans;
}
};
返回所有可能的结果
遇到分支的时候,所有分支都去走深度优先遍历
class Solution {
// 当前来到的动态规划中的格子,(L,R)
// path .... [pl....pr] ....
void process(std::vector<std::vector<int>> &dp,
string &str, int L, int R,
std::string path, int pl, int pr,
std::vector<std::string> &ans){
if(L >= R){
if(L == R){
path[pl] = str[L];
}
ans.emplace_back(path.c_str());
}else{
if(dp[L][R - 1] == dp[L][R] - 1){
path[pl] = str[R];
path[pr] = str[R];
process(dp, str, L, R - 1, path, pl + 1, pr - 1, ans);
}
if(dp[L + 1][R] == dp[L][R] - 1){
path[pl] = str[L];
path[pr] = str[L];
process( dp, str, L + 1, R, path, pl + 1, pr - 1, ans);
}
if(str[L] == str[R] && dp[L + 1][R - 1] == dp[L][R]){
path[pl] = str[L];
path[pr] = str[R];
process( dp, str,L + 1, R - 1, path, pl + 1, pr - 1, ans);
}
}
}
public:
std::vector<std::string> minInsertions(string str) {
int N = str.size();
std::vector<std::vector<int>> dp(N, std::vector<int>(N, 0));
for (int i = 0; i < N - 1; ++i) {
dp[i][i + 1] = (str[i] == str[i + 1]) ? 0 : 1;
}
for (int i = N - 3; i >= 0; --i) {
for (int j = i + 2; j < N; ++j) {
dp[i][j] = std::min(dp[i][j - 1], dp[i + 1][j]) + 1;
if(str[i] == str[j]){
dp[i][j] = std::min(dp[i + 1][j - 1], dp[i][j]);
}
}
}
std::vector<std::string> ans;
std::string path(N + dp[0][N - 1], ' ');
process(dp, str, 0, N - 1, path, 0, (int)path.size() - 1, ans);
return ans;
}
};
为什么没有恢复现场:因为每次遍历都会覆盖之前的
类似题目
题目 | 思路 |
---|---|
leetcode:1312. 让字符串成为回文串的最少插入次数 | |
leetcode:214. 让字符串成为回文串的最少插入次数,返回一种可能的结果shortest-palindrome | |
leetcode:516. 最长回文子序列 Longest Palindromic Subsequence | |
leetcode:336. 回文对Palindrome Pairs |