从零开始的CPP(23)动态规划解决最长回文串

leetcode5

给你一个字符串 s,找到 s 中最长的

回文串

示例 1:

复制代码
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

最开始我是将回文串都存入map。使用substr进行切割,i为起始,j-i+1是步长

cpp 复制代码
string longestPalindrome(string s) {
    if (s.length() <= 1) {
        return s;
    }
    map<int,string> resultmap;
    string temp;
    for (int i = 0; i < s.length() - 1; i++) {
        for (int j = i; j < s.length(); j++) {               
            //cout << "temp:" << temp << endl;
            string s1 = s.substr(i, j-i+1);
            temp = s1;
            reverse(temp.begin(), temp.end());
            //cout << "s1:" << s1 << endl;
            if (temp == s1) {
                resultmap[i] = s1;
                //cout << "s1:" << s1 << endl;
            }
            
        }
    }
    int length = 0;
    int index = 0;
    for (int i = 0; i < resultmap.size(); i++) {
        if (resultmap[i].length() > length) {
            length = resultmap[i].length();
            index = i;
        }
    }
    return resultmap[index];
}

优化了一下,还是时间复杂度高

cpp 复制代码
string longestPalindrome(string s) {
    if (s.length() <= 1) {
        return s;
    }
    //map<int,string> resultmap;
    string temp;
    int max = 0;
    string maxstr;
    for (int i = 0; i < s.length() - 1; i++) {
        for (int j = i; j < s.length(); j++) {                             
            string s1 = s.substr(i, j - i + 1);
            temp = s1;
            if (s1.length() > max){
               reverse(temp.begin(), temp.end());
               //cout << "s1:" << s1 << endl;
               //cout << "temp:" << temp << endl;
               if (temp == s1) {
                   maxstr = s1;
                   max = s1.length();
                   //cout << "s1:" << s1 << endl;
               }
            }               
        }
    }
    
    return maxstr;
}

最终还是用动态规划的方式解决。动态规划的核心思想把已经发生过的情况储存起来,需要时直接调用,也就是空间换时间。

dp存储了某一段字符串是否是回文串,dp[i][j]的值如果为true,表示字符串s中从下标i到下标j的子串是一个回文串;如果为false,则不是回文串。

动态规划需要递推,所以也需要初始化,这里需要初始化单个字符串与连续字符串的情况,之后递推。

cpp 复制代码
string longestPalindrome(string s) {
    int n = s.length();
    if (n <= 1) {
        return s;
    }
    vector <vector<bool>> dp(n, vector<bool>(n, false));
    for (int i = 0; i < s.length(); i++) {
        dp[i][i] = true;
    }
    for (int i = 0; i < s.length()-1; i++) {
        if (s[i]==s[i+1])
        {
            dp[i][i+1] = true;
            dp[i+1][i] = true;
        }
    }
    int index=0;
    int maxlen=0;
    for (int len = 1; len < s.length(); len++) {
        for (int j = 0; j + len < s.length(); j++) {
            //cout << s[j] << endl << s[j + len]<<endl;
            if (s[j] == s[j + len] && dp[j + 1][j + len - 1]==true) {
                dp[j][j + len] = true;
                dp[j+len][j] = true;
                index = j;
                maxlen = len;
                cout << "找到回文" << ":";
                cout << index << "," << maxlen;
            }
        }
    }
    string res = s.substr(index, maxlen+1);
    return res;
}
相关推荐
野生技术架构师2 分钟前
2026 Java面试宝典(春招/社招/秋招通用):没有前言,只有答案,直接开背
java·开发语言·面试
计算机安禾8 分钟前
【数据库系统原理】第4篇:关系数据结构的形式化定义:域、笛卡尔积与关系模式
数据结构·数据库·算法
手写码匠20 分钟前
手写 DeepSeek 推理引擎优化:从 FP16 到 INT4 的量化加速实战
人工智能·深度学习·算法·aigc
GuWenyue22 分钟前
LeetCode 76 最小覆盖子串|JS 滑动窗口标准解法
前端·算法·面试
一只齐刘海的猫44 分钟前
【Leetcode】移动零
算法·leetcode·职场和发展
人道领域1 小时前
【LeetCode刷题日记】131.分割回文串,动态规划优化
java·开发语言·leetcode
z落落1 小时前
C# 接口 interface (多接口实现、类+接口、成员重名)
java·开发语言
王老师青少年编程1 小时前
信奥赛C++提高组csp-s之搜索进阶(迭代加深IDDFS)
c++·csp·信奥赛·csp-s·提高组·iddfs·埃及分数
liulilittle2 小时前
我从 BBRv1 到 KCC 的思考
网络·c++·tcp/ip·计算机网络·tcp·bbr·通信
落羽的落羽2 小时前
【项目】JsonRpc框架——开发实现1(细节功能、字段定义、抽象层、具象层)
linux·服务器·网络·c++·人工智能·算法·机器学习