leetcode第5题:最长回文子串--中心扩散法、动态规划法

上次写的代码简直没法看。

第一个思路答案上叫中心扩散法:

就是以一个字母为轴进行左右的比较,如果相同继续比较,如果不同,停止比较轴往前进一个。另外考虑到回文子串可为双数可为单数,那么考虑用0.5为轴的步长

class Solution(object):
    def longestPalindrome(self, s):
        if len(s)<=1:
            return s
        else:
            s_r=s[0:1]
            length_r = length_cur = 1
            for i in range(1,2*len(s)-2):#比如s长度等于6的时候,轴从0.5到4.5(第9个0.5)
                left_point = int(i*0.5-0.5)
                right_point = int(i*0.5+1)
                while left_point != -1 and right_point != len(s):
                    if s[left_point]==s[right_point]:
                        left_point += -1/2
                        right_point = int (right_point+1)
                    else:
                        break
                length_cur = right_point - left_point-1
                if length_cur>length_r:
                    length_r=length_cur
                    s_r=s[left_point+1:right_point]
            return s_r

 第二个思路动态规划法:

观察这道题其实如果按照普通的暴力列举法的话需要判断C^{2}n个子串

即:

s[0:0]~s[0:n]、

s[1:1]~s[1:n]、

...

s[n:n]、

其中有些串的判断是关联的,比如判断s[1:4]是否是回文,充要条件是s[2:3]满足回文,且s[1]==s[4]。

即可以写出状态转移方程:

                                P(i,j)=P(i+1,j-1)\wedges[i]==s[j]

所以P(i,j)需要依赖P(i+1,j-1),那就可以构造二维列表dp[][]用来记录,上代码

class Solution:
    def longestPalindrome(self, s):
        n=len(s)
        length_r=1
        index_head=0
        dp=[[False]*n for p in range(n)]#初始化dp表
        for i in range(n):
            dp[i][i]=True#初始化对角线
        for i in range(1,n):#列标,[1,n)
            for j in range(i):#行标[0,i),不能碰到对角线
                if i-j == 1:
                    if s[i] == s[j]:
                        dp[i][j] = True
                        if i-j+1>length_r:
                            length_r=i-j+1
                            index_head=j
                else:
                    if dp[i-1][j+1] == True and s[i] == s[j]:
                        dp[i][j] = True
                        if i-j+1>length_r:
                            length_r=i-j+1
                            index_head=j
        return s[index_head:index_head+length_r]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值