leetcode:214. 让字符串成为回文串的最少插入次数,返回一种可能的结果

题目来源

题目描述

在这里插入图片描述

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值