题目: Longest Palindromic Substring
链接:https://leetcode.com/problems/longest-palindromic-substring/?tab=Description
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example:
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
Example:
Input: "cbbd" Output: "bb"
解题思路:
首先,本题解题思路有几种,我自己做的时候想到的是最蠢的一种(我自己感觉),后面再介绍比较简单的方法以及优化的方法。
思路一:本题目的是为了找出最长的回文子串,所谓回文串就是正着读和反着读都一样,即我把原串逆过来写,它跟原串的最长公共子串就是我们的目标。第一步把原串逆过来得到S',for循环遍历原串,内层循环遍历S',遍历的时候有技巧,不需要把整个S'都遍历完,遍历的次数跟两个东西相关,第一是跟当前找到的最大子串相关,因为如果S'遍历到剩下的字符个数不大于当前最大子串长度的时候,继续遍历没有意义,即使再找到回文串也不是我们要的答案;第二是跟原串遍历到的位置有关,原串S第i个字符反过来之后是S'的第(len(S) - 1 - i)个,如果到了这里都还没匹配上就不需要继续遍历下去了,所以第二层循环根据这个原则能少遍历很多次。具体实现看代码。
思路二:这个思路我一开始没想到,后来别人启发的,应该说是逻辑最简单的思路。假设原串aabcabacbda,我们对原串做一下处理a|a|b|c|a|b|a|c|b|d|a
,遍历这个扩充的字符串上每一个字符,然后检查左右两边字符,相等则再继续检查下一位,不相等则结束,判断是否相等时跳过“|”,这样就能找出所有回文串,然后判断哪个最长作为输出。该方法不复杂度跟第一个方法都是O(n^2)
思路三:思路三是思路二的一个扩充,可以将复杂度降低为O(n),这个解释有点长,我也是从别人博客学习而来的,这里就直接贴上链接大家可以过去学习一下。O(n)!!!非常厉害:http://blog.csdn.net/hopeztm/article/details/7932245 (这篇博客里介绍的最后一个方法)
思路一源代码:
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
s_len = len(s)
if s_len == 0:
return ''
elif s_len == 1:
return s
s_r = ''
for i in range(0, s_len):
s_r += s[s_len-1 - i]
max_substr = s[0]
max_len = 1
for i in range(0, s_len):
for j in range(0, s_len - max_len - i):
if s[i] != s_r[j]:
continue
flag = True
temp_max_len = s_len - j - i
temp_max_substr = s[i:s_len-j]
for m in range(1, temp_max_len):
temp_i = i+m
temp_j = j+m
# print temp_i, temp_j
if temp_i + temp_j >= (s_len-1):
break
if s[temp_i] != s_r[temp_j]:
flag = False
break
if flag and temp_max_len > max_len:
max_substr = temp_max_substr
max_len = temp_max_len
break
return max_substr