• LeetCode之“字符串”:最长回文子串


      题目要求:

      给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。例如,给出字符串 "abcdzdcab",它的最长回文子串为 "cdzdc"。

      

      解答:

      这个题目的一个简单的解法就是对字符串中的每一个字符,同时向其两边延展,以找到最长回文子串。这种方法是可以的,但要处理回文子串长度为奇数和偶数的两种情况是比较麻烦的。如下图的几个字符串:

      “a”

      "aa"

      "aaa"

      "aaaa"

      一个比较好的解决方法就是利用Manacher算法。这个算法的核心思想在于为原字符串的开头结尾以及每两个相邻的字符之间加入一个特殊的字符,例如‘#’,以达到统一处理回文子串长度为奇数和偶数的两种情况的目的。如一个字符串为S = “abaaba”,处理之后就是S' = “#a#b#a#a#b#a#”。这样,不管回文子串的长度是奇数还是偶数,我们都可以统一处理,因为通过添加特殊字符,原偶数长度的子串中间多了一个特殊字符,这样就能够将其他和奇数长度的字符串一样处理了。我们只需在最后将特殊字符去掉即可。详细可参考LeetCode上的一篇文章

      在LeetCode上通过的C++代码如下:

     1 class Solution {
     2 public:
     3     /**
     4      * @param s input string
     5      * @return the longest palindromic substring
     6      */
     7     string longestPalindrome(string& s) {
     8         int sz = s.size();
     9         string newStr;
    10         for(int i = 0; i < sz; i++)
    11         {
    12             newStr += "#" + s.substr(i, 1);
    13         }
    14         newStr += "#";
    15         
    16         int szOfNewStr = newStr.size();
    17         int center = 0;
    18         int len = 0;
    19 
    20         for(int i = 0; i < szOfNewStr; i++)
    21         {
    22             int step = 1;
    23             int k = i;
    24             int tmpCenter = i;
    25             int tmpHalfLen = 0;
    26             int tmpLen = 0;
    27             
    28             if(newStr[i] == '#')
    29             {
    30                 while(k - step > -1 && k + step < szOfNewStr && newStr[k - step] == newStr[k + step])
    31                 {
    32                     tmpHalfLen++;
    33                     step += 2;
    34                 }
    35                 tmpLen = 2 * tmpHalfLen;
    36             }
    37             else
    38             {
    39                 step++;
    40                 while(k - step > -1 && k + step < szOfNewStr && newStr[k - step] == newStr[k + step])
    41                 {
    42                     tmpHalfLen++;
    43                     step += 2;
    44                 }
    45                 tmpLen = 2 * tmpHalfLen + 1;
    46             }
    47         
    48             if(tmpLen > len)
    49             {
    50                 len = tmpLen;
    51                 center = tmpCenter;
    52             }
    53                 
    54         }
    55         
    56         string retStr;
    57         if(newStr[center] == '#')
    58         {
    59             int i = 1;
    60             while(i < len)
    61             {
    62                 retStr.insert(retStr.begin(), newStr[center - i]);
    63                 retStr.insert(retStr.end(), newStr[center + i]);
    64                 i += 2;
    65             }
    66         }
    67         else
    68         {
    69             retStr += newStr[center];
    70             int i = 2;
    71             while(i < len)
    72             {
    73                 retStr.insert(retStr.begin(), newStr[center - i]);
    74                 retStr.insert(retStr.end(), newStr[center + i]);
    75                 i += 2;
    76             }
    77         }
    78         
    79         return retStr;
    80 
    81     }
    82 };
    View Code

      

      另外,代码已托管至Github.

  • 相关阅读:
    IllegalStateException
    TimeUnit简析
    Cron表达式
    任务调度之Timer与TimerTask配合
    Executor简析
    this逃逸
    SQL、SQL Server、MySQL与Oracle
    数据库与实例
    vw 、vh、vmin 、vmax
    逻辑(内存)分页与物理分页
  • 原文地址:https://www.cnblogs.com/xiehongfeng100/p/4524134.html
Copyright © 2020-2023  润新知