最长回文子串 Longest Palindromic Substring

本文详细介绍了四种寻找最长回文子串的方法,包括暴力解法、动态规划、中心扩展法和Manacher's Algorithm。每种方法都有其独特的时间和空间复杂度,旨在帮助读者理解和实现高效解决回文子串问题的算法。

思路:

方法一:暴力,时间复杂度O(n^3),空间复杂度O(1)

不断判断子串是否回文。

//Longest Palindromic Substring
string longestPalindrome(string s) {
    int length=s.size();
    int maxLength=1;
    int start=0;
    for(int i=0;i<length;i++) {
        for(int j=i+1;j<length;j++) {
            int tmp1,tmp2;
            for(tmp1=i,tmp2=j;tmp1<tmp2;tmp1++,tmp2--) {
                if(s.at(tmp1)!=s.at(tmp2)) break;
            }
            if(tmp1>=tmp2 && j-i+1 >maxLength) {
                maxLength = j-i+1;
                start=i;
            }
        }
    }
    if(maxLength>0) {
        return s.substr(start,maxLength);
    }
    return NULL;
}

方法二:DP,时间复杂度O(n^2),空间复杂度,O(n^2)

p[i][j]表示以i开始j结束的子串是否满足回文:

p[i][j]==1 是回文子串;

p[i][j]!=1 不是回文子串;

状态转移方程:

p[i][i]=1;

p[i][i+1]=1 : if s[i]==s[i+1]

p[i][j]=1 : if s[i]==s[j] && p[i+1][j-1]=1


class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        int longestBegin = 0;
        int maxLen = 1;
        bool table[1000][1000] = {false};
        for(int i=0;i<n;i++) {
            table[i][i] = 1;
        }
        for(int i=0;i<n-1;i++) {
            if(s[i] == s[i+1]) {
                table[i][i+1]=1;
                maxLen=2;
                longestBegin=i;
            }
        }
        for(int len=3;len<=n;len++) {
            for(int i=0;i<n-len+1;i++) {
                int j=i+len-1;
                if(s[i]==s[j] && table[i+1][j-1]==1) {
                    table[i][j]=1;
                    maxLen=len;
                    longestBegin=i;
                }
            }
        }
        return s.substr(longestBegin,maxLen);
    }
};

方法三:中心扩展法

设字符串s长度为n

对于长度为奇数的回文子串,沿着中心字符轴对称,可能的中心点共有n个;

对于长度为偶数的回文子串,沿着中心空字符轴对称,可能的中心点共有n-1个;

所以我们可以一个一个中心点的去试探,判断以此为中心的子串是否是回文子串。

class Solution {
public:
    string longestPalindrome(string s) {
        const int length=s.size();
        if(length == 0) return "";
        int maxLength=1;
        int start=0;
     
        for(int i=0;i<length;i++) {
            int j=i-1,k=i+1;
            while(j>=0 && k<length && s[j]==s[k]) {
                if(k-j+1 > maxLength) {
                    maxLength=k-j+1;
                    start=j;
                }
                j--;
                k++;
            }
        }
        for(int i=0;i<length;i++) {
            int j=i,k=i+1;
            while(j>=0 && k<length && s[j]==s[k]) {
                if(k-j+1 > maxLength) {
                    maxLength=k-j+1;
                    start=j;
                }
                j--;
                k++;
            }
        }
        return s.substr(start,maxLength);
    }
};

方法四:Manacher‘s Algorithm

这个算法的时间复杂度在O(n),空间复杂度也为O(n),学习完这个算法觉得设计的太巧妙了!充分利用了回文串的对称性。

看了好几篇介绍的博文,这篇写的最易理解:《Manacher's algorithm:优雅的求最长回文子串》

class Solution {
public:
    string preProcess(string s) {
        int n=s.length();
        if(n==0) return "^$";
        string ret="^";
        for(int i=0;i<n;i++) {
            ret += "#"+s.substr(i,1);
        }
        ret += "#$";
        return ret;
    }

    string longestPalindrome(string s) {
        string T = preProcess(s);
        const int n = T.length();
        int P[n];
        int center = 0, mx = 0;
        for(int i=1;i<n-1;i++) {    //i从第一个“#”循环到到最后一个“#”
            int i_mirror = 2*centor-i;
            //P[i] = (mx > i) ? min(P[i_mirror], mx - i) : 0;
            if(mx > i) {
                if(i+P[i_mirror] < mx) {
                    P[i] = P[i_mirror];
                }else {
                    P[i] = mx - i;
                }
            }else {
                P[i] = 0;
            }
            
            //calculate P[i] at i
            while(T[i + 1 + P[i]] == T[i - 1 - P[i]]) {
                P[i]++;
            }
            //update center and mx
            if(i + P[i] > mx) {
                center = i;
                mx = i + P[i];
            }
        }
        //find the maximum element in P
        int max_len = 0;
        int centor_index = 0;
        for(int i=1; i<n-1; i++) {
            if(P[i]>max_len) {
                max_len = P[i];
                centor_index = i;
            }
        }
        return s.substr((centor_index - 1 - max_len)/2, max_len);
    }
};



AI 代码审查Review工具 是一个旨在自动化代码审查流程的工具。它通过集成版本控制系统(如 GitHub 和 GitLab)的 Webhook,利用大型语言模型(LLM)对代码变更进行分析,并将审查意见反馈到相应的 Pull Request 或 Merge Request 中。此外,它还支持将审查结果通知到企业微信等通讯工具。 一个基于 LLM 的自动化代码审查助手。通过 GitHub/GitLab Webhook 监听 PR/MR 变更,调用 AI 分析代码,并将审查意见自动评论到 PR/MR,同时支持多种通知渠道。 主要功能 多平台支持: 集成 GitHub 和 GitLab Webhook,监听 Pull Request / Merge Request 事件。 智能审查模式: 详细审查 (/github_webhook, /gitlab_webhook): AI 对每个变更文件进行分析,旨在找出具体题。审查意见会以结构化的形式(例如,定位到特定代码行、题分类、严重程度、分析和建议)逐条评论到 PR/MR。AI 模型会输出 JSON 格式的分析结果,系统再将其转换为多条独立的评论。 通用审查 (/github_webhook_general, /gitlab_webhook_general): AI 对每个变更文件进行整体性分析,并为每个文件生成一个 Markdown 格式的总结性评论。 自动化流程: 自动将 AI 审查意见(详细模式下为多条,通用模式下为每个文件一条)发布到 PR/MR。 在所有文件审查完毕后,自动在 PR/MR 中发布一条总结性评论。 即便 AI 未发现任何值得报告的题,也会发布相应的友好提示和总结评论。 异步处理审查任务,快速响应 Webhook。 通过 Redis 防止对同一 Commit 的重复审查。 灵活配置: 通过环境变量设置基
【直流微电网】径向直流微电网的状态空间建模与线性化:一种耦合DC-DC变换器状态空间平均模型的方法 (Matlab代码实现)内容概要:本文介绍了径向直流微电网的状态空间建模与线性化方法,重点提出了一种基于耦合DC-DC变换器的状态空间平均模型的建模策略。该方法通过数学建模手段对直流微电网系统进行精确的状态空间描述,并对其进行线性化处理,以便于系统稳定性分析与控制器设计。文中结合Matlab代码实现,展示了建模与仿真过程,有助于研究人员理解和复现相关技术,推动直流微电网系统的动态性能研究与工程应用。; 适合人群:具备电力电子、电力系统或自动化等相关背景,熟悉Matlab/Simulink仿真工具,从事新能源、微电网或智能电网研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握直流微电网的动态建模方法;②学习DC-DC变换器在耦合条件下的状态空间平均建模技巧;③实现系统的线性化分析并支持后续控制器设计(如电压稳定控制、功率分配等);④为科研论文撰写、项目仿真验证提供技术支持与代码参考。; 阅读建议:建议读者结合Matlab代码逐步实践建模流程,重点关注状态变量选取、平均化处理和线性化推导过程,同时可扩展应用于更复杂的直流微电网拓扑结构中,提升系统分析与设计能力。
内容概要:本文介绍了基于物PINN驱动的三维声波波动方程求解(Matlab代码实现)理信息神经网络(PINN)求解三维声波波动方程的Matlab代码实现方法,展示了如何利用PINN技术在无需大量标注数据的情况下,结合物理定律约束进行偏微分方程的数值求解。该方法将神经网络与物理方程深度融合,适用于复杂波动题的建模与仿真,并提供了完整的Matlab实现方案,便于科研人员理解和复现。此外,文档还列举了多个相关科研方向和技术服务内容,涵盖智能优化算法、机器学习、信号处理、电力系统等多个领域,突出其在科研仿真中的广泛应用价值。; 适合人群:具备一定数学建模基础和Matlab编程能力的研究生、科研人员及工程技术人员,尤其适合从事计算物理、声学仿真、偏微分方程数值解等相关领域的研究人员; 使用场景及目标:①学习并掌握PINN在求解三维声波波动方程中的应用原理与实现方式;②拓展至其他物理系统的建模与仿真,如电磁场、热传导、流体力学等题;③为科研项目提供可复用的代码框架和技术支持参考; 阅读建议:建议读者结合文中提供的网盘资源下载完整代码,按照目录顺序逐步学习,重点关注PINN网络结构设计、损失函数构建及物理边界条件的嵌入方法,同时可借鉴其他案例提升综合仿真能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值