算法w3——Longest Palindromic Substring(leetcode 5)

题目: 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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值