打卡第十七天(Task17)----最长回文子串

Leetcode刻意练习----字符串5

题目

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2

输入: "cbbd"
输出: "bb"

题解一(暴力算法)

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if s == None:
            return None
        if s == s[::-1]:
            return s
        a = s[0]
        l = 1
        for m in range(len(s) - 1):
            for n in range(m + 1, len(s)):
                if s[m:n + 1] == s[m:n + 1][::-1] and n - m + 1 > l:
                    l = n - m + 1
                    a = s[m:n + 1]
        return a

在这里插入图片描述
可见暴力算法是真心的慢,看了一些题解之后,学习了两种高端的算法:马拉车算法和动态规划,以下是摘抄的两个题解中的算法。

题解二(manacher法)

假如字符串是奇数个,那么我们可以通过遍历所有字符串,再对所有字符串进行左右匹配,就像中心扩散方法一样。然后得到长度最大的字符串
但是如果字符串是偶数个,我们无法进行此操作
这个算法的最终要的额一点就是,我们将一个偶数长/奇数长的字符串,构造成新的字符串。
这样我们可以对新字符串的每个字符,进行左右匹配。

 def mancher(self, s:str) -> str:
        if len(s) < 2:
            return s
        # 将一个可能是偶数长/奇数长的字符串,首位以及每个字符间添加#
        test = '#'+'#'.join(s)+'#'
        # 当前遍历的中心最大扩散步数,其值等于原始字符串的最长回文子串的长度
        max_len = 0
        for i in range(len(test)):
            left = i - 1
            right = i + 1
            step = 0
            print(test[i])
            while left >= 0 and right < len(test) and test[left] == test[right]:
                # print("spread",test[left],test[right])
                left -= 1
                right += 1
                step += 1
                # print(step)
            
            if step > max_len:
                max_len = step
                start = (i - max_len) // 2
        return s[start: start + max_len

题解三(动态规划)

特判,当s的长度为1或者0时,返回s。

初试化最长回文子串的开始索引start和最长长度max_len=1

初试化dp数组,为n*n,全部初始化为False。dp[i][j]表示]s[i−j]是否为回文串。

将dp中,所有单个字符处都是回文串,置为True。s中若相邻的字符串相同,则同样将着两个字符对应的位置置为True。即遍历s:

dp[i][i]=True,表示单个字符一定是回文串。
若i<n−1 and s[i]==s[i+1],表示相邻的字符相同。则dp[i][i+1]=True,并更新最长回文子串的开始索引start=i和长度max_len=2
此时,从长度3,开始遍历,遍历区间[3,n+1),表示所有最长子串可能的长度。因为长度为1和2的已经在上一步找完了。对于可能的长度l:

从索引0开始遍历,遍历区间[0,n−l+1),对于开始索引i。**遍历区间解释:**因为开始索引为i,长度为l,则子串右侧索引为i+l−1,为了保证不越界,i+l−1<n,则i<n−+1l。
令子串右侧索引r=i+l−1
若满足s[i]==s[r] and dp[i+1][r−1]==True。表示子串s[i+1,…,r−1]为回文且s[i]==s[r],说明s[i,…,r]也是回文。则此时,更新dp[i][r]=True,并更新最长子串开始索引start=i和长度max_len=l
返回s[start,…,start+max_len−1]

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if(not s or len(s)==1):
            return s
        n=len(s)
        dp=[[False]*n for _ in range(n)]
        max_len=1
        start=0
        for i in range(n):
            dp[i][i]=True
            if(i<n-1 and s[i]==s[i+1]):
                dp[i][i+1]=True
                start=i
                max_len=2
        for l in range(3,n+1):
            for i in range(n+1-l):
                r=i+l-1
                if(s[i]==s[r] and dp[i+1][r-1]):
                    dp[i][r]=True
                    start=i
                    max_len=l
        return s[start:start+max_len]

内容概要:本文介绍了一种利用元启发式算法(如粒子群优化,PSO)优化线性二次调节器(LQR)控制器加权矩阵的方法,专门针对复杂的四级倒立摆系统。传统的LQR控制器设计中,加权矩阵Q的选择往往依赖于经验和试错,而这种方法难以应对高维度非线性系统的复杂性。文中详细描述了如何将控制器参数优化问题转化为多维空间搜索问题,并通过MATLAB代码展示了具体实施步骤。关键点包括:构建非线性系统的动力学模型、设计适应度函数、采用对数缩放技术避免局部最优、以及通过实验验证优化效果。结果显示,相比传统方法,PSO优化后的LQR控制器不仅提高了稳定性,还显著减少了最大控制力,同时缩短了稳定时间。 适合人群:控制系统研究人员、自动化工程专业学生、从事机器人控制或高级控制算法开发的技术人员。 使用场景及目标:适用于需要精确控制高度动态和不确定性的机械系统,特别是在处理多自由度、强耦合特性的情况下。目标是通过引入智能化的参数寻优手段,改善现有控制策略的效果,降低人为干预的需求,提高系统的鲁棒性和性能。 其他说明:文章强调了在实际应用中应注意的问题,如避免过拟合、考虑硬件限制等,并提出了未来研究方向,例如探索非对角Q矩阵的可能性。此外,还分享了一些实践经验,如如何处理高频抖动现象,以及如何结合不同类型的元启发式算法以获得更好的优化结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值