• 算法:最大回文子串问题


    自己在2014年12月面试某公司时被问过该问题。虽然当时,自己写出来了自认为效率比较高的算法,但是没有能按照面试官的要求,进行进一步的优化。后来网上搜索该问题,结果引申了一串其他的知识点,看来还是得深究啊!

    解法一:暴力法

    这种方法就不用多说了吧。这里我给出暴力法中,最优化的方案。

    # coding:utf-8
    
    ''' 由于是要求最长的回文串,所以我们可以从最长的子串开始遍历。当找到一个回文串后,就可以直接返回
    了。不用再遍历那些短的子串了。
    对于字符串s, 假设串长度为N,判断过程如下:
    1. 最长的子串就是本身,所以判断s是不是子串。假如不是,进行下一步:
    2. 然后判断串长度为N - 1的子串是不是,即:s[:N - 1], s[1:]
    3. 依次进行下一轮判断.直到找到个是回文串的子串。
    
    '''
    # 判断s的子串:"s[i], s[i+1]... s[j]"是否是回文的
    def check(s, i, j):
        tmp = s[i:j + 1]
        #print tmp
        #return tmp == tmp.reverse()
        return tmp == tmp[::-1]
    
    def LongestPalindrome(s):
        if not s:
            return "", 0
        lenth = len(s)
        diffLen = lenth - 1
        #maxPalindrome = ""
        while diffLen >= 0:
            i = 0
            j = diffLen
            while j < lenth:
                 if check(s, i, j):
                    return  s[i:j+1], diffLen + 1
                 i += 1
                 j += 1
            diffLen -= 1

    解法二:中心扩展法O(n2)

    这个算法思想其实很简单,就是对给定的字符串S,分别以该字符串S中的每一个字符 c 为中心,向两边扩展,记录下以字符 c 为中心的回文子串的长度。时间复杂度为O(n2),空间复杂度仅为O(1)。
    但有一点需要注意的是,回文的情况可能是 a b a,也可能是 a b b a。

     1 // 分别向左右扩展,返回扩展后的字符串
     2 string expand(string s, int left, int right) {
     3     int len = s.size();
     4     while (left>=0 && right<len && s[left] == s[right]) 
     5     {
     6         left--;
     7         right++;
     8     }
     9     return s.substr(left+1, right-left-1);
    10 }
    11 
    12 // 求最长回文子串
    13 string longestPalindrome(string s) {
    14     int len = s.size();
    15     if(len<=1) return s;
    16 
    17     string longest;
    18     for (int i=0; i<len-1; i++) 
    19     {
    20         string p1 = expand(s, i, i);  // 奇数
    21         if (p1.size() > longest.size())
    22             longest = p1;
    23 
    24         string p2 = expand(s, i, i+1);  // 偶数
    25         if (p2.size() > longest.size())
    26             longest = p2;
    27     }
    28     return longest;
    29 }

    面试时个人能想到就是这两种方法。此外此题还有动态规划法,Manacher法,后缀树方法。其中动态规划法这里不予以介绍,可以参考相关后面列出的参考文献。另外的两节会另外单独介绍!

    参考文献:

    http://songlee24.github.io/2015/05/12/longest-palindromic-substring/

     

  • 相关阅读:
    前端接口设计
    前端协作流程
    编写jQuery插件
    jQuery插件之validation插件
    深入理解ajax系列第九篇——jQuery中的ajax
    前端学PHP之Smarty模板引擎
    第3选择-解决所有难题的关键思维,种下好的种子避免落入钻石交易
    阿里BCG重磅报告《人工智能,未来致胜之道》
    关于web开发前端h5框架的选择
    html5+php实现文件的断点续传ajax异步上传
  • 原文地址:https://www.cnblogs.com/bitpeng/p/4747957.html
Copyright © 2020-2023  润新知