码迷,mamicode.com
首页 > 其他好文 > 详细

最长回文字串

时间:2018-07-08 19:05:25      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:位置   根据   print   查看   奇数   回文字符串   nbsp   col   bsp   

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

示例 1:

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

示例 2:

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

简单易于理解的解法
 1 class Solution(object):
 2     def longestPalindrome(self, s):
 3         """
 4         :type s: str
 5         :rtype: str
 6         """
 7         n = len(s)
 8         maxL, maxR, max = 0, 0, 0
 9         for i in range(n):
10             # 长度为偶数的回文字符串
11             start = i
12             end = i + 1
13             while start >= 0 and end < n:
14                 if s[start] == s[end]:
15                     if end - start + 1 > max:
16                         max = end - start + 1
17                         maxL = start
18                         maxR = end
19                     start -= 1
20                     end += 1
21                 else:
22                     break
23 
24             # 长度为奇数的回文子串
25             start = i - 1
26             end = i + 1
27             while start >= 0 and end < n:
28                 if s[start] == s[end]:
29                     if end - start + 1 > max:
30                         max = end - start + 1
31                         maxL = start
32                         maxR = end
33                     start -= 1
34                     end += 1
35                 else:
36                     break
37         return s[maxL:maxR + 1]
38 
39 s=abcba
40 str=Solution.longestPalindrome(1,s)
41 print(str)

查看资料找到了manacher算法 

    这个算法是以每一个字符为中心, 向两边发散,同时,用一个数组p来记录以每一个字符为中心的回文串的一半的长度.

     先看一下该算法的核心.

     确定以第i个字符为中心的回文串长度,建立在p[1:i-1]这个数组基础上

     假设, mx为当前字符串中已经确定的回文串的最有端. po为以mx为右端的回文串的中心,

     这时候,我们需要确定 第i个字符的位置是 > ma 还是 i <= mx

     如果 i <= mx 就是当前要确定的字符包含在前面的某个回文串里面, 回文串是对称的, 所以找到i 相对于po的对称位置 j, 

     接下来, 我们要做的就是判断, ①p[j] >= mx - i  or ②p[j] < mx - i

      在第一种情况, 就是说以i为中心的回文串还有向 mx右边伸展的可能, 然而那一部分还是未知数, 就的一步一步的去求解, 第二种情况, 就是 p[j] <= mx - i, 根据回文串的堆成性质, 可以确定

      p[i] = p[j]

     当i > mx的时候也是需要我们去一步一步的求解

     我在实现的时候只是给出最长回文串的一个, 

 1 class Solution:
 2     def longestPalindrome(self, s):
 3         """
 4         :type s: str
 5         :rtype: str
 6         """
 7         s1 = # + #.join(s) + #
 8         length = len(s1)
 9         p = [0] * length
10         i = 0
11         id, mx = 0, 0
12         while i < length:
13             if mx > i:
14                 p[i] = min(mx - i, p[2 * id - i])
15             else:
16                 p[i] = 1
17             while (i - p[i] >= 0) and (i + p[i] < length) and (s1[i - p[i]] == s1[i + p[i]]):
18                 p[i] += 1
19             if (i - 1 + p[i]) > mx:
20                 mx = i - 1 + p[i]
21                 id = i
22             i += 1
23         max_length = max(p)
24         index_id = p.index(max_length)
25         s = s1[index_id + 1 - max_length:index_id + max_length]
26         s2 = ‘‘
27         for i in s.split(#):
28             s2 += i
29         return s2
30 s=aa
31 str=Solution.longestPalindrome(1,s)
32 print(str)

第二种方法还不太明白,为什么要加‘#’号

最长回文字串

标签:位置   根据   print   查看   奇数   回文字符串   nbsp   col   bsp   

原文地址:https://www.cnblogs.com/zhibei/p/9280804.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!