• C++算法:最短回文串


    LeetCode214最短回文串

    给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
    示例 1:
    输入:s = “aacecaaa”
    输出:“aaacecaaa”
    示例 2:

    输入:s = “abcd”
    输出:“dcbabcd”

    提示:
    0 <= s.length <= 5 * 104
    s 仅由小写英文字母组成

    分析

    我们可以将s分成两部分s1+s2,其中s1是回文,假定前面增加的字符串是s0。因为s0+s1+s2是回文,所以s0和s2是逆序。要想s0最短,就要s2最短,也就是s1最长。那么此题的本质就是:求s是回文的最长前缀。如果s不存在回文前缀,则认为s1为空。求出s1后,再求s0和s2,并返回s0+s1+s2。
    求回文至少有两种办法:一,枚举回文中心,时间复杂度O(n^2)。本题会超时。二,马拉车算法,时间复杂度O(n)。比较复杂,过些天专门写篇博文介绍马拉车算法。建议将马拉车算法封装成类。

    2023年4月版

    class Solution {
    public:
    string shortestPalindrome(string s) {
    if (“” == s)
    {
    return “”;
    }
    m_c = s.length();
    std::string s1 = Do(s);
    std::string strAdd;
    for (int i = s.length() - 1; i >= s1.length(); i–)
    {
    strAdd += s[i];
    }
    return strAdd + s;
    }
    string Do(const string& s)
    {
    vector next(m_c, -1);
    for (int i = 1; i < m_c; i++)
    {
    int iNext = next[i - 1];
    while ((-1 != iNext) && (s[iNext + 1] != s[i]))
    {
    iNext = next[iNext];
    }
    next[i] = (s[i] == s[iNext + 1]) ? iNext + 1 : iNext;
    }
    std::string sRever(s.rbegin(), s.rend());
    int i = 0, j = 0;
    while ((i {
    while ((i < m_c) && (j < m_c) && (s[i] == sRever[j]))
    {
    i++;
    j++;
    }
    if (i >= m_c - (j - i))
    {
    return s.substr(0, i);
    }
    if (j >= m_c)
    {
    return “”;
    }
    if ((i > 0) && (next[i - 1] >= 0))
    {
    i = next[i - 1] + 1;
    }
    else
    {
    if (i > 0)
    {
    i = 0;
    }
    else
    {
    j++;
    }
    }
    }
    return s.substr(0,1);
    }
    int m_c;
    };

    2023年8月版(马拉车)

    class CKMP
    {
    public:
    static vector Next(const string& s)
    {
    const int len = s.length();
    vector vNext(len, -1);
    for (int i = 1; i < len; i++)
    {
    int next = vNext[i - 1];
    while ((-1 != next) &&(s[next + 1] != s[i]))
    {
    next = vNext[next];
    }
    vNext[i] = next + (s[next + 1] == s[i]);
    }
    return vNext;
    }
    };
    class Solution {
    public:
    string shortestPalindrome(string s) {
    vector next = CKMP::Next(s);
    int n = s.length();
    int preSameIndex = -1;
    for (int i = n - 1; i >= 0; i–)
    {
    const auto& ch = s[i];
    while ((-1 != preSameIndex) && (s[preSameIndex + 1] != ch))
    {
    preSameIndex = next[preSameIndex];
    }
    if (ch == s[preSameIndex + 1])
    {
    preSameIndex++;
    }
    }
    string add = (preSameIndex == n - 1 ? “” : s.substr(preSameIndex + 1, n));
    reverse(add.begin(), add.end());
    return add + s;

    }
    
    • 1

    };

    其它

    视频课程

    如果你觉得复杂,想从简单的算法开始,可以学习我的视频课程。
    https://edu.csdn.net/course/detail/38771

    我的其它课程
    https://edu.csdn.net/lecturer/6176

    测试环境

    win7 VS2019 C++17

    相关下载

    算法精讲《闻缺陷则喜算法册》doc版
    https://download.csdn.net/download/he_zhidan/88348653

    作者人生格言
    有所得,以墨记之,故曰墨家
    闻缺陷则喜。问题发现得越早,越给老板省钱。
    算法是程序的灵魂

  • 相关阅读:
    matlab实现贪婪算法
    配置nginx动静分离全步骤
    窗口类介绍
    PostgreSQL创建数据库及修改参数文件
    生成对抗性网络简介
    基础篇——REST风格开发
    vue实现单页面仿照购物车案例——基于mint-ui和vue2.0
    ML之yellowbrick:基于titanic泰坦尼克是否获救二分类预测数据集利用yellowbrick对LoR逻辑回归模型实现可解释性(阈值图)案例
    PHP低版本安全问题
    图论篇--代码随想录算法训练营第五十六天打卡| 108. 冗余连接,109. 冗余连接II
  • 原文地址:https://blog.csdn.net/he_zhidan/article/details/133820795